ESLint "couldn't find an eslint.config file" (flat config) in CI
ESLint v9 looks for a flat config (eslint.config.js) by default. If your repo only has a legacy .eslintrc, ESLint reports that it could not find a config file and exits non-zero, failing the lint job.
What this error means
After upgrading to ESLint 9, the lint step fails immediately with "ESLint couldn't find an eslint.config.(js|mjs|cjs) file" even though .eslintrc.json is committed.
Oops! Something went wrong! :(
ESLint couldn't find an eslint.config.(js|mjs|cjs) file.Common causes
ESLint v9 defaults to flat config
From v9, ESLint reads eslint.config.js and no longer auto-loads .eslintrc.*. A repo carrying only the legacy file has, from v9's view, no config at all.
The config lives outside the working directory
CI runs ESLint from a directory above or beside the config, so the flat config in a subpackage is never discovered.
How to fix it
Add a flat config or opt into legacy lookup
- Migrate
.eslintrctoeslint.config.js, or run the migrator. - As a stopgap, set
ESLINT_USE_FLAT_CONFIG=falseso v9 reads the legacy file. - Re-run the lint step to confirm a config is found.
# stopgap: keep using the legacy .eslintrc under v9
ESLINT_USE_FLAT_CONFIG=false npx eslint .Run the official flat-config migrator
The migration tool converts a legacy config into eslint.config.js.
npx @eslint/migrate-config .eslintrc.jsonHow to prevent it
- Add
eslint.config.jsbefore upgrading to ESLint 9. - Pin the ESLint major version so the config format does not change under you.
- Run ESLint from the package root where the config lives.