You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
409 PessimisticConcurrencyConflict ("operation in progress") is treated as a hard failure instead of being retried #252
When APIM returns 409 PessimisticConcurrencyConflict ("Operation on the API is in progress") for a request against an API that has an async operation still settling, the CLI should treat it as a transient condition and retry with backoff. The conflict clears once APIM releases the API lock.
Actual behavior
Publishing an API that has revisions fails with:
ERROR NOOP api/: HTTP 409: {"error":{"code":"PessimisticConcurrencyConflict","message":"Operation on the API is in progress","details":null}}
Mechanism: publishApi publishes the root API (spec import) first, then publishes each revision sequentially (src/services/api-publisher.ts → publishApiRevisions → publishResource in a loop). The root import's async operation reports succeeded, so the CLI immediately issues the next operation on the same API (the first revision). APIM has not yet released the API-level lock from the just-completed import, so it returns 409 PessimisticConcurrencyConflict. There is no settle-wait between the root import completing and the next same-API call.
The retry logic then rejects it, because 4xx responses are deliberately not retried:
src/clients/apim-client.ts — "Do not retry client errors (4xx) — they are deterministic, not transient."
This is correct in general, but 409 PessimisticConcurrencyConflict / "operation in progress" is transient, not deterministic.
apiops CLI version
1.0.0
Environment details
Windows self-hosted agent; Node v24.15.0 / npm 11.12.1; Windows PowerShell 5.1; APIM SKU Developer.
Type: type:bug Effort: M — requires targeted fix in apim-client.ts retry logic to carve out PessimisticConcurrencyConflict as a retryable 409, plus possible settle-wait between root API import and revision publishes in api-publisher.ts. Well-scoped but needs careful backoff tuning and testing. Domain:src/clients/apim-client.ts (retry policy) · src/services/api-publisher.ts (publish sequencing) Confidence: high (90%) Uncertainty: none — clear bug report with root cause analysis, reproduction path, and exact file locations identified by the reporter.
Reasoning
The retry policy in apim-client.ts explicitly skips all 4xx responses as "deterministic," but 409 PessimisticConcurrencyConflict / "operation in progress" is a well-known transient APIM lock condition, not a client error. The fix is to exempt this specific error code from the 4xx-no-retry rule and apply exponential backoff, and optionally add a settle-wait between the root API import success and the first revision publish.
Recommended next steps
Confirm whether a settle-wait after root import (before revisions) is preferable to retry-on-409, or if both should be applied.
Decide max retry count and backoff parameters for this specific error code.
Add an integration test or unit test covering the retry path for PessimisticConcurrencyConflict.
Activity
github-actions commentedon Aug 31, 2026
🏷️ Triage Recommendation
Type: type:bug
Effort: M — requires targeted fix in
apim-client.tsretry logic to carve outPessimisticConcurrencyConflictas a retryable 409, plus possible settle-wait between root API import and revision publishes inapi-publisher.ts. Well-scoped but needs careful backoff tuning and testing.Domain:
src/clients/apim-client.ts(retry policy) ·src/services/api-publisher.ts(publish sequencing)Confidence: high (90%)
Uncertainty: none — clear bug report with root cause analysis, reproduction path, and exact file locations identified by the reporter.
Reasoning
The retry policy in
apim-client.tsexplicitly skips all 4xx responses as "deterministic," but409 PessimisticConcurrencyConflict / "operation in progress"is a well-known transient APIM lock condition, not a client error. The fix is to exempt this specific error code from the 4xx-no-retry rule and apply exponential backoff, and optionally add a settle-wait between the root API import success and the first revision publish.Recommended next steps
PessimisticConcurrencyConflict.fix: retry pessimistic concurrency conflicts (Fixes #252)