Fixing ESLint "no-console" Errors in Production While Keeping Debug Logs
When ESLint flags console.log statements in production code, the issue usually lies in mis‑configured no-console rules or environment overrides. This guide walks through diagnosing the problem, applying targeted overrides, and verifying the fix so you can keep debug logs without lint errors.
09 May 2026, 17:32 UTC

Recognizing the Problem
When running eslint on a production build you may see a flood of errors like:
src/utils/logger.js:10:5 error Unexpected console statement no-console
These errors appear even though console.log statements are intentionally left in the code for debugging or runtime diagnostics. The underlying cause is usually a mis‑configured no-console rule that is enforced globally or in the wrong environment.
Root Cause & Diagnostic Table
| Condition | Likely Cause | Diagnostic Check |
|---|---|---|
All console.* calls flagged as errors | Rule enabled globally without overrides | Search for "no-console": in the ESLint config |
Only console.log flagged, but console.warn passes | Rule configured with allow: ['warn', 'error'] | Inspect the rule’s options |
Overrides present in package.json but not applied | Incorrect override scope or missing file | Run eslint --print-config path/to/file.js |
Production code runs in Node, but rule is set for browser env | Environment mis‑match | Check env section of the config |
| Multiple ESLint config files exist | Linting uses the wrong file | Verify which config file ESLint is using |
Step‑by‑Step Diagnostic Checklist
- Locate the active ESLint configuration
- Run
eslint --print-config src/index.js(replace path with any file in production bundle). - Confirm the output shows
"no-console": "error"and theenvsection. - Note the
filePathfield in the printed config to verify which file ESLint loaded.
- Run
- Check for environment overrides
- Look for an
overridesarray that targets*.{js,jsx,ts,tsx}insrc/orbuild/. - Verify that the override sets
"no-console": "off"or["error", {"allow": ["warn", "error"]}]for the correct environment. - If missing, add an override scoped to production files:
module.exports = { // global rules rules: { "no-console": "error" }, overrides: [ { files: ["src/**/*.js"], env: { node: true }, rules: { "no-console": "off" } } ] }; - Look for an
- Validate environment variables in the linting command
- If your build script sets
NODE_ENV=production, ensure ESLint respects it:NODE_ENV=production eslint src/ --ext .js,.jsx. - Check that the
envproperty in the config reflects the runtime environment (e.g.,node: truefor server code).
- If your build script sets
- Inspect for multiple config files
- Search the repo for
.eslintrc.*files. - Determine which one is being used by ESLint by reading the
filePathfrom the print‑config output. - If the wrong file is in effect, either rename/remove the extraneous file or update your lint command to point to the correct config:
eslint --config .eslintrc.prod.json src/.
- Search the repo for
- Check plugin or shareable config overrides
- If you extend a shareable config (e.g.,
eslint-config-airbnb), that config may setno-consoleglobally. - Override it locally after the
extendsline:
module.exports = { extends: ["airbnb"], rules: { "no-console": "off" } }; - If you extend a shareable config (e.g.,
Applying Fixes and Verifying the Result
- Run the linter again
- Command:
eslint src/ --ext .js,.jsx - Expected: No
no-consoleerrors for production files. - Check the exit code; it should be
0if no errors remain.
- Command:
- Confirm the rule is off in the printed config
- Command:
eslint --print-config src/utils/logger.js | grep "no-console" - Output should show
"no-console": "off"or the allowed list.
- Command:
- Re‑run the production build
- Ensure that the build script still lints the code before bundling.
- Verify that the build passes without ESLint errors.
Escalation Criteria
If after the above steps the no-console rule still flags production code, consider:
- Reviewing
eslint-plugin-nodeor other environment‑specific plugins that might re‑enable the rule. - Checking for
--envflags passed to the linter in CI scripts that override the config. - Ensuring that the lint command is actually executed in the CI pipeline (look at CI logs for lint step).
- Consulting the team’s logging policy to confirm that disabling the rule is acceptable.
Practical Example
Suppose you have the following file in src/logger.js:
export function log(msg) {
console.log(msg); // intentional debug output
}
And your current .eslintrc.json looks like this:
{
"env": { "browser": true },
"rules": { "no-console": "error" }
}
After following the diagnostic steps, you update the config to:
{
"env": { "browser": true },
"rules": { "no-console": "error" },
"overrides": [
{
"files": ["src/**/*.js"],
"env": { "node": true },
"rules": { "no-console": "off" }
}
]
}
Running eslint src/ --ext .js now completes without no-console errors, while the rule remains active for any other code outside src/.
Takeaway
Mis‑configured no-console rules typically stem from global enforcement or environment mismatches. By inspecting the active config, applying targeted overrides, and verifying via --print-config, you can keep useful debug logs in production without compromising linting standards.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.