Jest "coverage threshold ... not met" - Fail-the-Build Coverage in CI
Tests all passed, but Jest exited non-zero because coverage dropped below a configured threshold. Either new code is genuinely untested, or coverage collection is misconfigured so untouched files drag the number down.
What this error means
CI fails after a green test run with "Jest: coverage threshold for statements (80%) not met: 76.4%." The failure is the coverage gate, not an assertion - the suite itself is passing.
Jest: "global" coverage threshold for statements (80%) not met: 76.42%
Jest: "global" coverage threshold for branches (75%) not met: 70.1%Common causes
New code added without tests
A feature or branch was added but not covered. Global thresholds compare total coverage, so even well-tested files cannot offset a large uncovered addition.
collectCoverageFrom pulls in untested files
A broad collectCoverageFrom glob counts files that no test imports (configs, barrels, generated code) as 0% covered, sinking the global average.
How to fix it
Cover the new code or scope thresholds per path
Add tests for the uncovered lines, or set realistic per-glob thresholds so unrelated areas are not held to the same bar.
// jest.config.js
module.exports = {
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.stories.tsx'],
coverageThreshold: {
global: { statements: 80, branches: 75 },
'src/legacy/**': { statements: 40 },
},
};See exactly what is uncovered
- Run
jest --coveragelocally and open the text/HTML report. - Exclude files that should never be counted (types, generated, stories) from
collectCoverageFrom. - Add tests for the specific uncovered lines the report highlights.
How to prevent it
- Exclude non-testable files from
collectCoverageFrom. - Use per-path thresholds so legacy areas do not block new work unfairly.
- Review coverage in PRs so regressions are caught before merge.