cypress test retries exhausted but passes locally
Shows how to debug Cypress tests that exhaust retries in CI while passing locally. Covers order dependence, shared state, testIsolation, and seed data. Use when retries burn through in CI on a spec that is green on your machine. Not for tests that fail locally too, for real product bugs the test caught, or for retry config syntax questions.
TL;DR
Passing locally and failing in CI after retries usually means the test depends on state or timing that differs between the two. Run the spec alone and in suite order, then hunt for shared state. Retries mask flakiness; they do not fix it.
Error
Running: specs/checkout.cy.js
checkout flow
1) completes a purchase
2) completes a purchase
3) completes a purchase
0 passing
3 failing
The test failed after 2 retries and will not be retried again.Steps
- Run only the failing spec locally with the same retry settings as CI. Expected: this tells you whether the spec alone is flaky or only fails in suite order.
- Run the full suite locally in the same order CI uses. Expected: if it fails here too, the cause is order dependence, not the CI machine.
- Look for state shared between tests: database rows, localStorage, files on disk, or a logged-in session leaking across specs. Expected: you can name the shared state.
- Seed the data each test needs inside a beforeEach hook instead of relying on a previous spec:
beforeEach(function() {
cy.task('db:seed')
cy.visit('/checkout')
})Expected: every test starts from the same known state.
- Confirm testIsolation is true (the Cypress 12 default) so page state resets between tests, and move any cross-test setup into cy.session(). Expected: no test depends on another test's leftovers.
- Re-run in CI. Expected: green on the first attempt, not just after retries.
When to use
- A spec passes locally but burns through retries in CI
- The failure moves between tests from run to run
- The suite recently grew past a handful of specs
When not to use
- The test also fails locally (debug it locally first; CI adds nothing)
- The test caught a real bug (fix the app, not the test)
- You only want to change retry counts (see the retries config docs instead)
Tool compatibility
- Cypress 12 through 14, testIsolation and cy.session()
- retries config in cypress.config.js or per-spec
- Any CI provider; the pattern is provider-independent
Variant phrasings
Test retries exhausted in CI pipeline
Same debugging path. Start by reproducing the order locally before touching timeouts.
Flaky test passes on retry locally but never in CI
Local retries can hide a timing assumption that CI always violates. Remove the retry crutch and fix the wait.
Why it happens
Local runs are often a single warm spec with leftover state that happens to help. CI runs the whole suite cold, in order, on a slower box. Tests that read state written by an earlier test, or that assume fast responses, pass by luck locally and fail honestly in CI.
Edge cases
- Fails in CI even run alone: the difference is the environment, not order. Check baseUrl, seed data, and third-party services in CI.
- Passes in CI sometimes: true timing flake. Replace fixed waits with request or DOM waits.
- Only fails on the first CI run of the day: stale or missing seed data. Make seeding part of the job, not a manual step.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_k0U5rGNrRzGMlpCaCaKFrA
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.