Skip to content

[Bug]: [Python] Modeless ARM LRO callback references undefined response #11966

Description

Describe the bug

When generating a synchronous, modeless Python ARM client, an LRO operation whose final response has a JSON body but no response headers produces invalid Python code.

With models-mode=none, the generated get_long_running_output callback references response without assigning it:

def get_long_running_output(pipeline_response):
    if response.content:
        deserialized = response.json()
    else:
        deserialized = None

When the long-running operation reaches a successful terminal state, the callback raises:

NameError: name 'response' is not defined

The callback should first assign the HTTP response:

def get_long_running_output(pipeline_response):
     response = pipeline_response.http_response
     if response.content:
         deserialized = response.json()
     else:
         deserialized = None

The current implementation in
 packages/http-client-python/generator/pygen/codegen/serializers/builder_serializer.py 
only emits  response = pipeline_response.http_response  when one of these conditions is true:

  • models are enabled;
  • models-mode == "dpg" ; or
  • the LRO final response contains response headers.

However,  response_headers_and_deserialization(...)  can still emit code that reads response.content when models-mode=none and the final response has no headers.

This is also a generated-output regression: an earlier TypeSpec-generated ARM client emitted the response assignment for the equivalent LRO callback.

Reproduction

Reproduction

Reproduced with:

- Node.js 24.18.0
- `@typespec/compiler` 1.15.0
- `@azure-tools/typespec-python` 0.63.5
- `@typespec/http-client-python` 0.36.0
- `@azure-tools/typespec-azure-resource-manager` 0.71.0
- `@azure-tools/typespec-client-generator-core` 0.71.1

Create `main.tsp`:

```typespec
import "@typespec/rest";
import "@typespec/http";
import "@azure-tools/typespec-azure-resource-manager";
import "@typespec/versioning";

using Azure.ResourceManager;
using Versioning;
using Http;

@armProviderNamespace
@versioned(Versions)
namespace Microsoft.LroResponseRepro;

interface Operations extends Azure.ResourceManager.Operations {}

enum Versions {
  @armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v5)
  @Azure.Core.previewVersion
  `2025-01-01-preview`,
}

model WidgetProperties {
  value: string;
  ...DefaultProvisioningStateProperty;
}

model Widget is TrackedResource<WidgetProperties> {
  ...ResourceNameParameter<Widget>;
}

@armResourceOperations
interface Widgets {
  get is ArmResourceRead<Widget>;
  createOrUpdate is ArmResourceCreateOrReplaceAsync<Widget>;
  delete is ArmResourceDeleteWithoutOkAsync<Widget>;
}

Compile it with:

tsp compile main.tsp \
  --emit @azure-tools/typespec-python \
  --option "@azure-tools/typespec-python.models-mode=none" \
  --option "@azure-tools/typespec-python.no-async=true" \
  --option "@azure-tools/typespec-python.namespace=lro_repro" \
  --option "@azure-tools/typespec-python.emitter-output-dir=./generated"

Inspect  generated/lro_repro/operations/_operations.py .
The generated  begin_create_or_update  callback reads  response.content  without first assigning
 response = pipeline_response.http_response .

### Checklist

- [x] Follow our [Code of Conduct](https://github.com/microsoft/typespec/blob/main/CODE_OF_CONDUCT.md)
- [x] Check that there isn't already an issue that request the same bug to avoid creating a duplicate.
- [x] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/Microsoft/typespec/discussions).
- [x] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingemitter:client:pythonIssue for the Python client emitter: @typespec/http-client-python

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions