Skip to content

Add linter rule arm-post-lro-response-mismatch for ARM POST LRO operations#4145

Draft
markcowl with Copilot wants to merge 55 commits into
mainfrom
copilot/add-linter-for-arm-post-lro
Draft

Add linter rule arm-post-lro-response-mismatch for ARM POST LRO operations#4145
markcowl with Copilot wants to merge 55 commits into
mainfrom
copilot/add-linter-for-arm-post-lro

Conversation

Copilot AI commented Mar 28, 2026

Copy link
Copy Markdown
Contributor
  • New rule arm-post-lro-response-mismatch for ARM POST LRO operations
  • Response-based checking logic driven by HTTP status codes:
    • If 200 response exists: non-void body must match finalResult; void/empty body means finalResult should be "void"
    • If 204 without 200: finalResult should be "void"
    • If both 200 (void body) and 204: finalResult should be "void"
    • If both 200 (non-void body) and 204: emit new conflictingResponses diagnostic (POST should not have both 204 NoContent and 200 OK with a non-empty body)
    • If only 202: check template instantiation of Azure.ResourceManager.ActionAsync (fully-qualified name) for Response param match with finalResult
  • doesFinalResultMatch checks both namespace-qualified name equality (for named types) and isAssignableTo from typekit for type compatibility
  • Void matching: "void" finalResult is compared against TypeSpec builtin void type via isVoidType
  • Uses resolveArmResources for both resource-level and provider-level actions
  • Codefix arm-post-lro-set-final-result using ArmLroLocationHeader<FinalResult = ResponseType> — handles:
    • Existing ArmLroLocationHeader alone → replace with FinalResult version
    • ArmLroLocationHeader in intersection → replace just that part
    • No LroHeaders parameter → append it after last template arg
  • Fix in resolveArmResourceOperations: raw @armResourceAction operations (with simple HTTP paths like /generate) are now properly discovered by matching against already-resolved resources when path-based resolution fails. Previously these operations were silently dropped because getResourceInfo couldn't derive ARM resource type info from relative paths.
  • Tests use ...ResourceNameParameter<Employee> throughout
  • Tests refactored to use it.each for parameterized type matching/non-matching scenarios
  • Low-level (non-template) tests use ArmAcceptedLroResponse for proper LRO constructs: invalid case (200 with Model body + ArmAcceptedLroResponse) and valid case (204 + ArmAcceptedLroResponse)
  • Tests cover: 200 body mismatch, 204 void check, ArmResourceActionAsyncBase with 200 body check, ActionAsync 202-only template check, low-level non-template LRO operations with ArmAcceptedLroResponse, conflicting 200+204 responses, and codefix
  • All tests pass, files formatted correctly
  • Documentation page added for the rule
  • Merged latest from main, regenerated docs — only PR-related files differ

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library label Mar 28, 2026
…-lro-response-mismatch

Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/7bf3456e-7b67-406e-a438-d26cf5637117

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copilot AI changed the title [WIP] Add a linter to check Response value matches FinalResult for ARM LRO POST Add linter rule arm-post-lro-response-mismatch for ARM POST LRO operations Mar 28, 2026
Copilot AI requested a review from markcowl March 28, 2026 00:57

@markcowl markcowl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot Pull the latest from main and then apply the fixes in the comments. Ensure that all tests pass and all files are correctly formatted.

Copilot AI and others added 2 commits March 31, 2026 18:30
…r-arm-post-lro

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Pull the latest from main and then apply the fixes in the comments. Ensure that all tests pass and all files are correctly formatted.

Pulled latest from main, applied all review fixes, and verified all 286 tests pass with correct formatting. Changes in a9c28e6.

Copilot AI requested a review from markcowl March 31, 2026 18:58
@markcowl

Copy link
Copy Markdown
Member

@copilot Please pull the latest from main, regenrate docs for tyepspec-azure-resource-manager, validate that all files are correctly formatted.

Copilot AI commented Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please pull the latest from main, regenrate docs for tyepspec-azure-resource-manager, validate that all files are correctly formatted.

Pulled latest from main (already up to date at a228fc5), regenerated docs for typespec-azure-resource-manager (added the new rule to README.md and linter.md), validated formatting, and confirmed all 286 tests pass. Done in 7e87831.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the meta:website TypeSpec.io updates label Mar 31, 2026

@markcowl markcowl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please pull the latest from main, make the changes suggested, ensure all tests are passing and all files are correctly formatted.

Copilot AI commented Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

Please pull the latest from main, make the changes suggested, ensure all tests are passing and all files are correctly formatted.

Pulled latest from main (already up to date), added the fallback for non-template operations that checks the 200 response body vs final-result-schema, and verified all 288 tests pass with correct formatting. Done in fcb4809.

Copilot AI requested a review from markcowl March 31, 2026 20:28

@markcowl markcowl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot please perform the investigation suggested and add a fix, if possible

Copilot AI and others added 3 commits June 2, 2026 01:07
Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
…r-arm-post-lro

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Raw operations decorated with @armResourceAction have simple HTTP paths
(e.g. "/generate") that getResourceInfo cannot resolve into ARM resource
type info. Previously these operations were silently dropped.

Now, when getResourceInfo returns undefined for an operation, the code
tries to match it against already-resolved resources by comparing the
operation's resource model name against path segments. A deferred pass
handles cases where the matching resource hasn't been resolved yet.

Updated the low-level LRO test to expect the diagnostic (since the
operation is now properly discovered).

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please perform the investigation suggested and add a fix, if possible

Done. Investigated and fixed the issue. Raw @armResourceAction operations were being silently dropped by resolveArmResourceOperations because their simple HTTP paths (e.g., /generate) couldn't be resolved into ARM resource type info by getResourceInfo. Added fallback matching logic that associates these operations with their parent resource by matching the model name against path segments of already-resolved resources. The low-level test now correctly expects the diagnostic. All 325 tests pass.

Copilot AI requested a review from markcowl June 2, 2026 01:23
@microsoft-github-policy-service microsoft-github-policy-service Bot added the stale Mark a PR that hasn't been recently updated and will be closed. label Jun 16, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown

Hi @@copilot. Your PR has had no update for 14 days and it is marked as a stale PR. If it is not updated within 14 days, the PR will automatically be closed. If you want to refresh the PR, please remove the stale label.

@microsoft-github-policy-service

Copy link
Copy Markdown

Hi @@copilot. This PR will be closed since it has had no update for 28 days. If this change is still relevant, please reopen the PR.

@markcowl markcowl reopened this Jul 10, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the linter Issues related to linter rules label Jul 10, 2026
@markcowl

Copy link
Copy Markdown
Member

@copilot Please pull the latest from main, ensure that all tests pass and all files are correctly formatted, and ensure that only the changes associated with this pr are in the pr diff/

…r-arm-post-lro

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please pull the latest from main, ensure that all tests pass and all files are correctly formatted, and ensure that only the changes associated with this pr are in the pr diff/

Done in 42100f6. Pulled latest from main (merged cleanly), all 368 tests pass, all files formatted correctly, only PR-related files in the diff.

@markcowl markcowl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot Pull the latest from main, make the suggested changes, ensure all files are correctly formatted, pass spell check, and that all tests pass. Ensure that only the changes associated with this pr are in the pr diff

@@ -0,0 +1,363 @@
import {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

rename this rule to 'lro-response-mismatch"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed in commit that was just pushed. The rule is now lro-response-mismatch, and all files, const names, docs, tests, and references have been updated to match.

/**
* Verify that the final result of an ARM LRO POST operation matches the Response parameter.
*/
export const armPostLroResponseMismatchRule = createRule({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

rename the rule to lro-response-mismatch and update the files and the associated name of this const, docs and tests to match

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in the latest commit. Rule renamed to lro-response-mismatch, file renamed to arm-lro-response-mismatch.ts, export renamed to armLroResponseMismatchRule, all docs/tests/references updated.

export const armPostLroResponseMismatchRule = createRule({
name: "arm-post-lro-response-mismatch",
severity: "warning",
url: "https://azure.github.io/typespec-azure/docs/libraries/azure-resource-manager/rules/post-lro-response-mismatch",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Need to add another check to ensure that the final response for a long-running PUT or PATCH matches the resource type and the final response for a delete operation matches void. This should add other messages

mismatchedPutOperation: The final result type of operation ${"operationName"} does not match the resource type. Please use standard Async templates or set the FinalResult type in the 201 response.

mismatchedPatchOperation: The final result type of operation ${"operationName"} does not match the resource type. Please use standard Async templates or set the FinalResult type in the 202 response.

mismatchedPDeleteOperation: The final result type of operation ${"operationName"} does not match the resource type. Please use standard Async templates or set the FinalResult type in the 202 response to void.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot also need to regen samples and ensure no errors

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in the latest commit. Three new message IDs:

  • mismatchedPutOperation: checks createOrUpdate lifecycle ops, final result must match resource type
  • mismatchedPatchOperation: checks update lifecycle ops, final result must match resource type
  • mismatchedDeleteOperation: checks delete lifecycle ops, final result must be void

Tests added for each: valid cases using standard templates (ArmResourceCreateOrReplaceAsync, ArmResourcePatchAsync, ArmResourceDeleteWithoutOkAsync) and invalid cases with mismatched FinalResult. All 374 tests pass.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Regenerated samples and fixed the rule to handle header-only models (like RetryAfterHeader and ArmCombinedLroHeaders) as effectively void from a body perspective. The isHeaderOnlyModel check ensures that models with only @header/@statusCode properties don't trigger a mismatch when the 200 response body is empty. All 69 sample tests pass with no errors, all 374 ARM package tests pass.

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Pull the latest from main, make the suggested changes, ensure all files are correctly formatted, pass spell check, and that all tests pass. Ensure that only the changes associated with this ...

Done. Pulled latest from main (already up to date), renamed rule to lro-response-mismatch, added PUT/PATCH/DELETE LRO checks, all 374 tests pass, spell check passes (0 issues), all files formatted correctly, only PR-related files in the diff.

Copilot AI and others added 2 commits July 10, 2026 22:42

@markcowl markcowl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot Pull the latest from main, make the suggested changes, ensure that all tests pass, all changed files are correctly formatted, documentation is regenerated, and only the files associated with this pr are in the pr diff.

Comment thread packages/typespec-azure-resource-manager/src/rules/arm-lro-response-mismatch.ts Outdated
…main

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Pull the latest from main, make the suggested changes, ensure that all tests pass, all changed files are correctly formatted, documentation is regenerated, and only the files associated with ...

Done. Pulled latest from main (already up to date), removed codefix and all supporting code/tests, rewrote documentation as user-facing text, regenerated docs, formatted all files. All 372 tests pass, only PR-related files in the diff.

@markcowl

Copy link
Copy Markdown
Member

@copilot there is a merge conflict, please pull the latest, resolve the conflict, make sure only the changes associated with this pr are in the pr diff and update the pr

…r-arm-post-lro

# Conflicts:
#	packages/typespec-azure-resource-manager/src/linter.ts

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@copilot there is a merge conflict, please pull the latest, resolve the conflict, make sure only the changes associated with this pr are in the pr diff and update the pr

Resolved the merge conflict in packages/typespec-azure-resource-manager/src/linter.ts (kept both the new armFeatureFileUsageDiscourage import from main and our armLroResponseMismatchRule import). All 377 tests pass, files formatted, only PR-related files in the diff.

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

Labels

int:azure-specs Run integration tests against azure-rest-api-specs lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library linter Issues related to linter rules meta:website TypeSpec.io updates stale Mark a PR that hasn't been recently updated and will be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linter] Add a linter to warn if the Response value doesn't match the FinalResult for ARM LRO POST

3 participants