When devel migrates to eslint 9 flat config and disables rules the old shareable configs enabled, every partner // eslint-disable-next-line <rule> for those rules becomes an “Unused eslint-disable directive” warning — and yarn lint --max-warnings 0 turns warnings into build failures. Found on FKITDEV-9197 (CIB / portal_css); the same mechanism applies to any partner branch merging an eslint-9 migration.

A rule going from "on" to "off" breaks code that was complying with it

This is counter-intuitive: disabling a rule should only ever make lint quieter. It doesn’t, because eslint separately reports directives that suppress nothing. The partner files were never wrong — they were correctly suppressing a rule that core has since switched off.

The mechanism

devel’s eslint.config.mjs dropped the compat bridge:

compat.extends('standard', 'plugin:n/recommended', 'plugin:jest-formatting/strict')

and replaced it with n.configs['flat/recommended'] + js.configs.recommended, then explicitly turned off:

  • no-empty
  • no-unused-vars
  • no-redeclare
  • no-useless-assignment

Any partner comment targeting one of those (plus no-console, which the old standard config carried) now suppresses nothing:

Unused eslint-disable directive (no problems were reported from 'no-empty').

That is a warning. yarn lint runs with --max-warnings 0. Warning ⇒ exit non-zero ⇒ red gate. On CIB this was 9 dead directives across 6 customization/ files.

The fix, and the trap in the fix

Delete the directive comment lines.

eslint --fix does NOT delete them — it blanks them

Running --fix replaces each dead directive comment with a whitespace-only line instead of removing the line. You end up lint-green but with stray blank lines scattered through the partner files, and the diff looks like unexplained whitespace churn. Delete the lines properly (editor / script), then re-run lint to confirm.

Check for it during a devel update

Do this in Phase 1.4 of devel-update-and-release-flow whenever the merge touches eslint.config.* or package.json’s eslint dependencies:

# did the merge change the lint config at all?
git diff --name-only <merge>^1..<merge> | grep -E 'eslint'
 
# which rules did devel turn off?
git diff <merge>^1..<merge> -- eslint.config.mjs | grep -E "'off'|off,"
 
# where does the partner suppress rules?
git grep -n 'eslint-disable' -- customization/
 
# and just run it — the directives report themselves
yarn lint

The last line is the honest one: eslint names every dead directive with the exact rule, so a single yarn lint run enumerates the whole list. The value of the greps is knowing before you run whether to expect a wave of them.

devel removed the eslint-plugin-jest-formatting dependency (commit 65ac214c feat: eslint 9 FKITDEV-6045) but eslint.config.mjs still references the rule 'jest-formatting/padding-around-all': 'warn'. It does not error only because that block is scoped to files: ['test/*', 'test/**/*'] and yarn lint runs --ignore-pattern "test/*" — so the block is never evaluated. Latent: enabling test linting detonates it.

This is the portal_css twin of the already-recorded vuer_css case ([[devel-update-and-release-flow#test-files-cannot-be-linted-in-vuer_css|Test files cannot be linted in vuer_css]]), where the eslint config references a missing jest-formatting plugin and exits 2 on devel’s own test files. Two repos, same abandoned-plugin residue, both hidden behind the same --ignore-pattern "test/*".

For Agents

Do not “fix” the dead jest-formatting reference as part of a devel update — it is pre-existing devel debt, out of scope, and touching it turns a partner merge into a core change. Record it; do not carry it.