Skip to content

Conversation

@iscai-msft
Copy link
Contributor

This test is causing issues for the Rust team because the spec specifies that the response will be a CancelResult, while the initial response is void. We think this test is trying to go for specific ARM behavior, as such, we are not changing the mockapi response, instead updating the spec to reflect what the mockapi returns

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 11, 2025

Open in StackBlitz

npm i https://pkg.pr.new/Azure/typespec-azure/@azure-tools/azure-http-specs@3506

commit: 19c9159

@azure-sdk
Copy link
Collaborator

All changed packages have been documented.

  • @azure-tools/azure-http-specs
Show changes

@azure-tools/azure-http-specs - fix ✏️

Update mgmt spec LRO to correspond to initial response being void

@azure-sdk
Copy link
Collaborator

You can try these changes here

🛝 Playground 🌐 Website

Copy link
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this scenario. Generally speaking, the POST response will never contain the final result, this is only returned after polling. We include the final result essentially just for swagger processors that don't understand x-ms-long-running-operation-options.

Having the poller return a 202 is not standard, but might be part of the required handling. In any case, void is not a final result, so it seems wrong to include it in the 'fake' 200 responses of the POST endpoint

Copy link
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous is actually the way this API is represented in most async APIs that only return cancel

Copy link
Member

@weidongxu-microsoft weidongxu-microsoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem may be on the mockapi.

@XiaofeiCao Can you check about live service response of action LRO with Location header? Do them typically have a body or not?

On the other hand, I don't think the initial response would be the form of CancelResult model (if it has a body) -- as mentioned by Mark as well.

@XiaofeiCao
Copy link
Contributor

XiaofeiCao commented Nov 12, 2025

Searched in my memory for this kind of operation, found one and it happened to behave exactly this way, where the initial response body is null and final response body is what's defined in spec.
See:
Definition: https://github.com/v-hongli1/azure-rest-api-specs/blob/2d3ca3c53d93f4c2a0ed83aaade710d5440c3f33/specification/compute/resource-manager/Microsoft.Compute/ComputeRP/stable/2023-09-01/runCommand.json#L169-L177
Live recording: https://github.com/Azure/azure-sdk-assets/blob/4644dcbbc384f13af7f9d5225e76f4ad80f9b35a/java/sdk/resourcemanager/azure-resourcemanager/src/test/resources/session-records/PrivateLinkTests.testPrivateEndpointE2E.json#L1907-L2002

typespec-autorest is ok with this too, see playground.

Not sure if there's real case that initial response body is not null while different from final response body schema, but I agree with Mark as well.

@jhendrixMSFT
Copy link
Member

I agree that there's value in having pollers work with non-conformant services when there's enough information to make unambiguous, forward progress. However, there was no indication here that this was the expectation.

I suggest that we add a new category of LROs in the Spector tests to cover these cases. The "pedantic" LROs follow the tsp/guidelines to the letter, and the "lenient" ones (like this one) do not, but have enough info that pollers can make forward progress.

If this is too disruptive, then at minimum, we must document cases where the mock deviates from the spec and there's an expectation that SDKs are able to cope with it.

@XiaofeiCao
Copy link
Contributor

XiaofeiCao commented Nov 13, 2025

Hi @jhendrixMSFT , the guideline you mentioned in your issue is for data-plane.
For ARM guideline for async POST, please refer to Call Action POST Asynchronously.

"202 + Location header + null response body" is actually the standard pattern in ARM:
image

IMHO, one should not rely on the response body even if it's returned, since I don't see any schema enforcement on the response body schema.

Some service even return the resource itself, see:
https://github.com/Azure/azure-sdk-assets/blob/7ac0639abb914c7e1357b607f2e219e755b43316/java/sdk/appplatform/azure-resourcemanager-appplatform/src/test/resources/session-records/EnterpriseTierTest.canCRUDApp.json#L4883

@jhendrixMSFT
Copy link
Member

Hmm that seems to contradict the vNext design guidelines (I'm familiar with the one you cited). Which one is correct?

IMHO, one should not rely on the response body even if it's returned, since I don't see any schema enforcement on the response body schema.
Some service even return the resource itself, see:

Can you clarify what you mean here? The Rust poller expects the specified status monitor schema to be returned since that's what's authored.

@XiaofeiCao
Copy link
Contributor

Hmm that seems to contradict the vNext design guidelines (I'm familiar with the one you cited). Which one is correct?

The Spector test cases under azure/resource-manager are for management-plane, hence the ARM guideline should be followed here.

The vNext design guideline you mentioned is for data-plane. You can tell from its introduction:
image

IMHO, one should not rely on the response body even if it's returned, since I don't see any schema enforcement on the response body schema.

By this I mean under ARM guideline, 202 + Location header should have no response body, and response body should be ignored by SDK even if service returns it.

@jhendrixMSFT
Copy link
Member

I thought the POR was to unify the LRO rules? But we can ignore that as it's a larger discussion.

What I'm struggling with is that the tsp says a CancelResult type is returned for the status monitor. Are we saying that the CancelResult type is only ever returned when we GET the status monitor URL and never returned in the initial response?

By this I mean under ARM guideline, 202 + Location header should have no response body, and response body should be ignored by SDK even if service returns it.

While it's a reasonable assumption, to be pedantic, the spec is unclear here. It does not make any mention of a body, or absence thereof. We should follow up with the ARM team to have them clarify the spec.

@XiaofeiCao
Copy link
Contributor

XiaofeiCao commented Dec 3, 2025

Hi Joel, I don't think the CancelResult in ArmResourceActionAsync is the status monitor. It should be the final result of the polling operation.
The behavior of 202+Location header is explicitly demonstrated in ARM guideline, that no response body should be returned:
image

The standard flow(for LRO POST) is basically:

  1. initial request, 202 + Location + Retry-After headers
  2. poll Location URL, keep polling if 202 + Location still
  3. until 200 + final response body

Or if it completes on initial request:

  1. initial request, 200 + final response body, done

@jhendrixMSFT
Copy link
Member

Thanks this helps. I think this can be closed and we'll follow up on our end.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants