What version of Oxlint are you using?
1.62.0
What command did you run?
oxlint --fix test.ts
What does your .oxlintrc.json (or oxlint.config.ts) config file look like?
What happened?
Disclosure: this issue was drafted with AI assistance and reviewed by me before submission, per the AI Usage Policy
What happened?
The auto-fix performs a literal find/findLast → some token swap and leaves the surrounding === undefined/!== undefined/== null/!= null comparison untouched. Since Array#some() always returns a boolean, the comparison becomes a constant — silently inverting (or trivializing) the branch logic.
Minimal reproduction
// test.ts
const arr = [1, 2, 3];
if (arr.find((x) => x === 2) === undefined) {
console.log('not found');
} else {
console.log('found');
}
After oxlint --fix
const arr = [1, 2, 3];
if (arr.some((x) => x === 2) === undefined) { // ← always false
console.log('not found'); // ← unreachable
} else {
console.log('found'); // ← always taken
}
All affected variants
All five comparison variants exhibit the same naive token-swap behavior:
| Input |
Auto-fixed to |
Result |
arr.find(p) === undefined |
arr.some(p) === undefined |
always false |
arr.find(p) !== undefined |
arr.some(p) !== undefined |
always true |
arr.find(p) == null |
arr.some(p) == null |
always false |
arr.find(p) != null |
arr.some(p) != null |
always true |
arr.findLast(p) === undefined |
arr.some(p) === undefined |
always false |
arr.findLast(p) !== undefined |
arr.some(p) !== undefined |
always true |
Runtime verification
const empty = [];
const has2 = [1, 2, 3];
// Original — correct
empty.find(x => x === 2) === undefined // true (no match)
has2.find(x => x === 2) === undefined // false (match)
// After autofix — broken
empty.some(x => x === 2) === undefined // false (always)
has2.some(x => x === 2) === undefined // false (always)
This caused a real production bug in our codebase where a deduplication check became inverted, causing every value to be flagged as a duplicate.
Comparison with upstream eslint-plugin-unicorn
Per the upstream rule docs:
This rule is fixable for .filter(…).length checks and .{findIndex,findLastIndex}(…)
This rule provides a suggestion for .{find,findLast}(…)
The upstream plugin deliberately classifies .find()/.findLast() rewrites as suggestions only (require human review) — quoting the original PR:
"because autofixing isn't safe in all cases." It seems Oxlint's port treats this as an autofix instead.
Expected behavior
Either:
- Produce a semantically correct fix that handles the surrounding comparison:
• arr.find(p) === undefined/== null → !arr.some(p)
• arr.find(p) !== undefined/!= null → arr.some(p)
- Mark the rewrite as a suggestion (not autofix) for
.find()/.findLast() patterns, matching upstream behavior.
What version of Oxlint are you using?
1.62.0
What command did you run?
oxlint --fix test.tsWhat does your
.oxlintrc.json(oroxlint.config.ts) config file look like?{ "categories": { "correctness": "off" }, "plugins": ["unicorn"], "rules": { "unicorn/prefer-array-some": "error" } }What happened?
Disclosure: this issue was drafted with AI assistance and reviewed by me before submission, per the AI Usage Policy
What happened?
The auto-fix performs a literal
find/findLast→sometoken swap and leaves the surrounding=== undefined/!== undefined/== null/!= nullcomparison untouched. SinceArray#some()always returns a boolean, the comparison becomes a constant — silently inverting (or trivializing) the branch logic.Minimal reproduction
After
oxlint --fixAll affected variants
All five comparison variants exhibit the same naive token-swap behavior:
arr.find(p) === undefinedarr.some(p) === undefinedfalsearr.find(p) !== undefinedarr.some(p) !== undefinedtruearr.find(p) == nullarr.some(p) == nullfalsearr.find(p) != nullarr.some(p) != nulltruearr.findLast(p) === undefinedarr.some(p) === undefinedfalsearr.findLast(p) !== undefinedarr.some(p) !== undefinedtrueRuntime verification
This caused a real production bug in our codebase where a deduplication check became inverted, causing every value to be flagged as a duplicate.
Comparison with upstream
eslint-plugin-unicornPer the upstream rule docs:
The upstream plugin deliberately classifies
.find()/.findLast()rewrites as suggestions only (require human review) — quoting the original PR:Expected behavior
Either:
•
arr.find(p) === undefined/== null → !arr.some(p)•
arr.find(p) !== undefined/!= null → arr.some(p).find()/.findLast()patterns, matching upstream behavior.