Command that triggered the bug
apiops publish
Expected behavior
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.
CI/CD environment
Azure DevOps
Is this bug blocking you?
Yes
Command that triggered the bug
apiops publish
Expected behavior
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.
CI/CD environment
Azure DevOps
Is this bug blocking you?
Yes