fix(server): retry cloud requests on HTTP 500#33718
Merged
Conversation
Add 500 to the list of retryable HTTP status codes in `isRetryableError` to align with the sibling `isRetryableCloudError` in `cloud_request.ts`, which already treats 500 as a transient/retryable response.
Capture-protocol upload now retries 3 times on HTTP 500 (matching the 503 path) since 500 is now part of the retryable status list. The test description, assertion, and snapshot are updated accordingly.
…dgkin-06f561 # Conflicts: # cli/CHANGELOG.md
…dgkin-06f561 # Conflicts: # cli/CHANGELOG.md
cacieprins
requested changes
May 5, 2026
Per review feedback, only retry on 500 for the Test Replay artifact upload (which is idempotent). Other cloud requests using the shared `isRetryableError` predicate may be non-idempotent — retrying after a 500 risks duplicating partially-applied work. The 500 retry is now applied as a local override at the upload call site in `put_protocol_artifact.ts`. The shared `isRetryableError` is restored to its previous status list.
isRetryableError now accepts an optional HTTP method. For idempotent methods (GET/HEAD/PUT/DELETE/OPTIONS), HTTP 500 is also retryable since replaying the request is safe. For non-idempotent methods (POST/PATCH) — or when the method is unknown — 500 is excluded to avoid duplicating partially-applied work. Updated each cloud API call site to pass its method, so: - Test Replay artifact upload (PUT) - Studio bundle fetch (GET) - cy.prompt bundle fetch (GET) now retry on 500 in addition to the always-retryable statuses, while: - Studio session creation (POST) - cy.prompt session creation (POST) continue to fail fast on 500 as before.
mschile
commented
May 5, 2026
cacieprins
approved these changes
May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Additional details
isRetryableErrorinpackages/server/lib/cloud/network/is_retryable_error.tswas treating HTTP 500 responses as non-retryable, while the siblingisRetryableCloudErrorinpackages/server/lib/cloud/api/cloud_request.tsalready retries on 500 (with the comment "retry on 500 - according to system test, this is expected behavior"). The legacy retry logic inpackages/server/lib/cloud/api/index.tsalso retries the entire 5xx range.This change adds
500to the retryable status list inisRetryableErrorso the fetch-based cloud request paths (protocol artifact upload, studio bundle/session, cy-prompt bundle/session) retry transient cloud 500s, matching behavior of the axios-based path.The unit test was updated to move
500from the non-retryable list to the retryable list.Note
Medium Risk
Changes cloud request retry behavior to treat HTTP 500 as retryable for idempotent methods, which could affect Cloud traffic patterns and error reporting. Scope is limited to retry classification and a few call sites plus test/snapshot updates.
Overview
Improves Cypress Cloud resiliency by retrying transient HTTP 500s for idempotent requests.
isRetryableErrornow accepts an optional HTTP method and will retry500only for idempotent methods (while keeping existing retry behavior for408/429/502/503/504).Cloud API callers using
asyncRetry(putProtocolArtifact, Studio andcy-promptbundle/session requests) now pass their HTTP method intoisRetryableErrorso uploads/downloads get the new behavior. Tests and system-test snapshots were updated to assert/reflect 3 retry attempts and the new aggregated error messaging when an upload keeps returning500.Reviewed by Cursor Bugbot for commit d2e1c63. Bugbot is set up for automated code reviews on this repo. Configure here.
Steps to test
yarn workspace @packages/server test-unit -- test/unit/cloud/network/is_retryable_error_spec.tsand confirm all assertions pass, including 500 now appearing in the retryable list.How has the user experience changed?
Transient HTTP 500 responses from Cypress Cloud during protocol artifact uploads, studio bundle fetches/sessions, and cy-prompt bundle fetches/sessions are now retried (3 attempts, linear 500ms backoff) instead of failing on the first occurrence.
PR Tasks
cypress-documentation?type definitions?