ESLint Exits 1 on Warnings - Fix --max-warnings 0 in CI
ESLint exits 0 when there are only warnings, so lint passes locally. CI commonly runs eslint --max-warnings 0, which makes any warning fail the job - so the same code that "passed" locally turns the pipeline red.
What this error means
CI fails on lint with exit 1 and a "too many warnings" summary, even though npx eslint . exits cleanly on your machine. The difference is the --max-warnings 0 flag in the CI command.
/app/src/App.tsx
12:7 warning 'foo' is assigned a value but never used @typescript-eslint/no-unused-vars
✖ 1 problem (0 errors, 1 warning)
ESLint found too many warnings (maximum: 0).Common causes
CI treats warnings as failures
--max-warnings 0 makes ESLint exit 1 if any warning exists. Locally, without the flag, the same warnings are informational and ESLint exits 0.
Warning-level rules accumulating
Rules configured as warn (unused vars, exhaustive-deps) pile up over time. They are invisible until a --max-warnings gate turns them into a hard CI failure.
How to fix it
Reproduce the CI gate locally
Run lint with the same flag CI uses so you see the failure before pushing.
npx eslint . --max-warnings 0
# fix each warning, or re-scope a rule to "off"/"error" deliberatelyClear or re-classify the warnings
- Fix the underlying warnings (remove unused vars, add missing deps).
- If a rule should not gate CI, set it to
off; if it should, set it toerrorso intent is explicit. - Run
--max-warnings 0consistently so warning debt can never accumulate unseen.
How to prevent it
- Run
eslint --max-warnings 0locally and in pre-commit, matching CI. - Decide each rule's severity deliberately -
offorerror, not lingeringwarn. - Keep the lint command identical across local and CI.