cypress We detected an uncaught exception from your application failing CI - how to fix
Handles Cypress failures caused by uncaught exceptions from the application under test in CI. Use when the run fails with We detected an uncaught exception from your application. Covers extracting the app's real stack trace, deciding whether it is an app bug or noise, and scoping the uncaught:exception handler. Not for errors in Cypress or test code.
TL;DR
Cypress fails the test when the application throws an uncaught exception, by design: an app that throws during the test is not behaving. The right response is almost always to read the application's stack trace, not Cypress's wrapper, and fix the app. Only when the exception is known-benign, typically from a third-party script, should you add a Cypress.on('uncaught:exception') handler, and then scoped to that specific error rather than returning false for everything.
The query
cypress We detected an uncaught exception from your application failing CI - how to fixUse this when
- We detected an uncaught exception from your application fails CI
- the app throws only with CI data or CI timing
- a third-party script throws in the CI environment
Not for
- errors thrown by Cypress itself or by your test code (those fail differently)
- uncaught exceptions that reproduce on every page locally (fix the app; no Cypress involvement needed)
- console errors that do not throw (Cypress ignores those by default)
Steps
1. Get the application's real stack trace
The CI artifacts hold the truth: the video, the screenshot at failure, and the browser console output. Read the app's error, not Cypress's summary.
We detected an uncaught exception from your application:
TypeError: Cannot read properties of undefined (reading 'user')
at renderProfile (https://example.com/static/js/main.js:412:18)Expected output: you have the app's stack trace with the throwing function and line.
2. Decide: app bug or known-benign noise
If the trace points at your code or your data, it is a bug: fix it. If it points at a third-party script (analytics, chat widget) throwing on CI-only conditions, it is noise worth suppressing narrowly.
# check whether the throwing script is yours or vendored
grep -rn "renderProfile" src/ | head -5Expected output: the exception is classified as a real bug or as identified third-party noise.
3. Fix the app, or scope the handler to the specific error
Fixing the app is the default. Suppression is the exception, and it must match the specific error so real regressions still fail.
// fix the app: guard the undefined access
const name = user?.profile?.name ?? 'Guest';
// or, for known-benign third-party noise only:
Cypress.on('uncaught:exception', (err) => {
if (err.message.includes('ThirdPartyWidget is not defined')) {
return false;
}
return true;
});Expected output: the app no longer throws, or the handler suppresses only the identified noise.
4. Verify the failure is gone in CI
Rerun the spec in CI and confirm no uncaught exception is reported and the handler, if any, did not swallow a different error.
npx cypress run --spec cypress/e2e/profile.cy.jsExpected output: the spec passes and the CI log shows no uncaught exception from the application.
Tool compatibility
- Cypress 10 - 14
- any browser Cypress supports
Variant phrasings
- We detected an uncaught exception from your application
- cypress uncaught exception failing CI but app works manually
- Cypress.on uncaught:exception not catching the error
Why it happens
Cypress instruments the application's window, so an uncaught exception in app code fails the currently running test. This is intentional fail-fast behavior: the test cannot meaningfully assert against a page whose JavaScript just crashed. CI exposes these because CI data, CI timing, and CI-only third-party behavior differ from local development.
Edge cases / pitfalls
- a global handler returning false for all errors masks real regressions; always match the specific message
- the handler receives the error before the test fails, so logging inside it helps classify new occurrences
- errors thrown during page load before cy.visit() resolves are still caught; check the visit itself when the trace is empty
- if the exception comes from a service worker or web worker, the stack looks different; check the browser console in the video
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_v68GGrrA3MwixUHQGlfEkw