Skip to content

feat: respect suppressions during autofix - #146

Merged
fasttime merged 5 commits into
eslint:mainfrom
sethamus:2026-respect-suppressions-during-autofix
Jul 13, 2026
Merged

fasttime merged 5 commits into
eslint:mainfrom
sethamus:2026-respect-suppressions-during-autofix

Conversation

@sethamus

Copy link
Copy Markdown
Contributor

Summary

This RFC proposes that ESLint should stop applying autofixes for a rule in any file where that rule is suppressed via the suppressions file.

Related Issues

eslint/eslint#20062

Comment thread designs/2026-respect-suppressions-during-autofix/README.md
@jfmengels

Copy link
Copy Markdown

In elm-review we don't apply automatic fixes for a rule when a file contains suppressions for that rule. I therefore wholeheartedly agree with this proposal. It works very well for us and I've never heard a complaint of this behavior (though we do have CLI options to ignore suppressions, I haven't checked if ESLint has similar flags).

Comment thread designs/2026-respect-suppressions-during-autofix/README.md Outdated
Comment thread designs/2026-respect-suppressions-during-autofix/README.md Outdated
Comment thread designs/2026-respect-suppressions-during-autofix/README.md
stevezhu added a commit to stevezhu/letuscook that referenced this pull request Apr 7, 2026

@nzakas nzakas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together. Generally I'm in favor of the behavior described in this RFC. I left a note about the technical implementation as I'm not quite following what you're envisioning.

Comment on lines +103 to +104
- `lib/cli.js`: for CLI runs with `--fix` or `--fix-dry-run`, resolve the active suppressions file before linting, load its current contents, and pass that suppressions snapshot into the `ESLint` instance used for fix generation. This makes autofix depend on the suppressions file contents loaded before linting begins.
- `lib/shared/translate-cli-options.js`: pass that internal suppressions snapshot through CLI option translation so it reaches the `ESLint` instance.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what the "suppressions snapshot" is?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply, I missed the notification. I added a definition paragraph to the RFC explaining what the “suppressions snapshot” is.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the idea to add a new option to the ESLint constructor that allows passing in the suppressions snapshot?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but strictly internal. I was thinking we could use an internal Symbol to pass the snapshot through the constructor options, similar to how disableCloneabilityCheck works, to avoid expanding the public API.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to keep the public API unchanged.

nzakas
nzakas previously approved these changes May 28, 2026

@nzakas nzakas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense as a feature and the plan looks sound to me.

Comment thread designs/2026-respect-suppressions-during-autofix/README.md Outdated
Comment thread designs/2026-respect-suppressions-during-autofix/README.md Outdated
Comment thread designs/2026-respect-suppressions-during-autofix/README.md Outdated
@nzakas

nzakas commented Jun 19, 2026

Copy link
Copy Markdown
Member

@sethamus there's some feedback for you to review here.

A **suppressions snapshot** is the in-memory representation of the `eslint-suppressions.json` file contents, read once at the start of the lint run. By capturing the suppressions data before linting begins, autofix decisions are based on a stable, point-in-time view of the file rather than a version that may change during the run (for example, if `--suppress-rule` writes new entries to the file during the same invocation).

- `lib/cli.js`: for CLI runs with `--fix` or `--fix-dry-run`, resolve the active suppressions file before linting, load its current contents, and pass that suppressions snapshot into the `ESLint` instance used for fix generation. This snapshot will be passed via the `ESLint` constructor options using an internal `Symbol`. This makes autofix depend on the suppressions file contents loaded before linting begins.
- `lib/eslint/eslint.js`: initialize `SuppressionsService` when suppressions are needed for fix filtering as well as reporting. For Node.js API calls with `applySuppressions` and `fix` enabled, load suppressions early enough in each `lintFiles()` or `lintText()` run before building the fixer. In `lintText()`, compute the suppressed rules only when `filePath` is provided and build the suppressions-aware fixer before passing it to `verifyText()`. For worker threads, pass the suppressions snapshot through `workerData`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note that the ESLint constructor already initializes a SuppressionsService (with filePath and cwd) and associates it with the new instance. I think that's all we need. For fix filtering in particular, a SuppressionsService shouldn't be necessary as the suppressions file location would be irrelevant.

@fasttime fasttime left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Leaving open for @mdjermanovic to review.

@mdjermanovic mdjermanovic left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! Moving to final commenting.

@mdjermanovic mdjermanovic added Final Commenting This RFC is in the final week of commenting and removed Initial Commenting This RFC is in the initial feedback stage labels Jul 3, 2026
@fasttime

Copy link
Copy Markdown
Member

There have been no further comments during the final comment period, so we can merge the RFC.

@fasttime
fasttime merged commit 227c8cc into eslint:main Jul 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Final Commenting This RFC is in the final week of commenting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants