Describe the bug
I noticed that after prolonged use of @antfu/eslint-config ESLint extension in VS Code will crash with an exception indicating infinite recursion like this one:
RangeError: Error while loading rule 'prefer-const': Maximum call stack size exceeded
Occurred while linting <input>
at Reflect.get (<anonymous>)
at Object.get (file:///Users/roman/Documents/dev/eslint-flat-config-recursion/node_modules/eslint-flat-config-utils/dist/index.mjs:32:24)
at Reflect.get (<anonymous>)
at Object.get (file:///Users/roman/Documents/dev/eslint-flat-config-recursion/node_modules/eslint-flat-config-utils/dist/index.mjs:32:24)
at Reflect.get (<anonymous>)
at Object.get (file:///Users/roman/Documents/dev/eslint-flat-config-recursion/node_modules/eslint-flat-config-utils/dist/index.mjs:32:24)
at Reflect.get (<anonymous>)
at Object.get (file:///Users/roman/Documents/dev/eslint-flat-config-recursion/node_modules/eslint-flat-config-utils/dist/index.mjs:32:24)
at Reflect.get (<anonymous>)
at Object.get (file:///Users/roman/Documents/dev/eslint-flat-config-recursion/node_modules/eslint-flat-config-utils/dist/index.mjs:32:24)
It was getting quite annoying to keep restarting ESLint server each time that happened so I decided to investigate and it led me to disableRuleFixes function in this repo.
|
export function disableRuleFixes(rule: Rule.RuleModule): Rule.RuleModule { |
|
if ((rule as any)[FLAG_DISABLE_FIXES]) { |
|
return rule |
|
} |
|
const originalCreate = rule.create.bind(rule) |
|
rule.create = (context): any => { |
|
const clonedContext = { ...context } |
|
const proxiedContext = new Proxy(clonedContext, { |
|
get(target, prop, receiver): any { |
|
if (prop === 'report') { |
|
return function (report: any) { |
|
if (report.fix) { |
|
delete report.fix |
|
} |
|
return (Reflect.get(context, prop, receiver) as any)({ |
|
...report, |
|
fix: undefined, |
|
}) |
|
} |
|
} |
|
return Reflect.get(context, prop, receiver) |
|
}, |
|
set(target, prop, value, receiver): any { |
|
return Reflect.set(context, prop, value, receiver) |
|
}, |
|
}) |
|
Object.defineProperty(proxiedContext, FLAG_DISABLE_FIXES, { value: true, enumerable: false }) |
|
return originalCreate(proxiedContext) |
|
} |
|
return rule |
|
} |
Here FLAG_DISABLE_FIXES is used to guard against repeatedly setting proxy. But the flag is set on proxiedContext while it's checked on the rule itself causing proxy to be set again and again. Which eventually leads to stack trace overflow.
Kind of hard to come up with a proper minimal repro so I created an artificial example that calls disableRuleFixes 10_000 times on a single rule and then runs that rule through ESLint. This consistently crashes it on my machine but you may need to increase number of iterations.
After I update disableRuleFixes function to correctly set flag on the rule itself - stack overflow error goes away.
Repro steps:
- Clone https://github.com/romansp/eslint-flat-config-recursion
- npm install
- run
node test-disable-rule-fixes.mjs
Expected: No exception is thrown.
Actual: Maximum call stack size exceeded exception is thrown.
Relevant thread in Discord: https://discord.com/channels/937808017016119440/937977751472840704/threads/1344413385986408561
Fix seems to be trivial and I'd like to submit a PR.
Reproduction
https://github.com/romansp/eslint-flat-config-recursion
System Info
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M1 Pro
Memory: 133.66 MB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.17.1 - ~/.nvm/versions/node/v22.17.1/bin/node
Yarn: 4.9.2 - ~/.nvm/versions/node/v22.17.1/bin/yarn
npm: 10.9.2 - ~/.nvm/versions/node/v22.17.1/bin/npm
bun: 1.2.19 - ~/.bun/bin/bun
Browsers:
Chrome: 138.0.7204.169
Safari: 18.5
Used Package Manager
npm
Validations
Contributions
Describe the bug
I noticed that after prolonged use of
@antfu/eslint-configESLint extension in VS Code will crash with an exception indicating infinite recursion like this one:It was getting quite annoying to keep restarting ESLint server each time that happened so I decided to investigate and it led me to
disableRuleFixesfunction in this repo.eslint-flat-config-utils/src/hijack.ts
Lines 26 to 56 in 45c6e98
Here
FLAG_DISABLE_FIXESis used to guard against repeatedly setting proxy. But the flag is set onproxiedContextwhile it's checked on theruleitself causing proxy to be set again and again. Which eventually leads to stack trace overflow.Kind of hard to come up with a proper minimal repro so I created an artificial example that calls
disableRuleFixes10_000 times on a single rule and then runs that rule through ESLint. This consistently crashes it on my machine but you may need to increase number of iterations.After I update
disableRuleFixesfunction to correctly set flag on the rule itself - stack overflow error goes away.Repro steps:
node test-disable-rule-fixes.mjsExpected: No exception is thrown.
Actual: Maximum call stack size exceeded exception is thrown.
Relevant thread in Discord: https://discord.com/channels/937808017016119440/937977751472840704/threads/1344413385986408561
Fix seems to be trivial and I'd like to submit a PR.
Reproduction
https://github.com/romansp/eslint-flat-config-recursion
System Info
System: OS: macOS 15.5 CPU: (10) arm64 Apple M1 Pro Memory: 133.66 MB / 32.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 22.17.1 - ~/.nvm/versions/node/v22.17.1/bin/node Yarn: 4.9.2 - ~/.nvm/versions/node/v22.17.1/bin/yarn npm: 10.9.2 - ~/.nvm/versions/node/v22.17.1/bin/npm bun: 1.2.19 - ~/.bun/bin/bun Browsers: Chrome: 138.0.7204.169 Safari: 18.5Used Package Manager
npm
Validations
Contributions