{"record":{"id":"b595fc46be221677","repo":"oxc-project/oxc","slug":"checking-equality-with-nan-will-always-return-fals","errorCode":null,"errorMessage":"Checking equality with NaN will always return false","messagePattern":"Checking equality with NaN will always return false","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/use_isnan.rs","lineNumber":28,"sourceCode":"use serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn comparison_with_nan(span: Span, operator: BinaryOperator) -> OxcDiagnostic {\n    let msg = match operator {\n        BinaryOperator::Inequality | BinaryOperator::StrictInequality => {\n            \"Checking inequality with NaN will always return true\"\n        }\n        BinaryOperator::Equality | BinaryOperator::StrictEquality => {\n            \"Checking equality with NaN will always return false\"\n        }\n        _ => \"Comparison with NaN will always return false\",\n    };\n    OxcDiagnostic::warn(msg)\n        .with_help(\"Use the `isNaN` function to compare with NaN.\")\n        .with_label(span)\n}\n\nfn switch_nan(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Checking `switch` discriminant against NaN will never match\")\n        .with_help(\"Use the `isNaN` function instead of the switch.\")\n        .with_label(span)\n}\n\nfn case_nan(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Checking for NaN in `case` clause will never match\")\n        .with_help(\"Use the `isNaN` function instead of the switch.\")\n        .with_label(span)\n}\n\nfn index_of_nan(method_name: &str, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/use_isnan.rs#L10-L46","documentation":"The `==`/`===` arm of oxlint's `use-isnan` comparison diagnostic: comparing anything for equality with NaN always yields false (NaN !== NaN by specification), so `x === NaN` guards a branch that can never execute. This arm carries an autofix via `make_equality_fix`.","triggerScenarios":"Equality comparisons with a literal NaN operand on either side: `value === NaN`, `NaN == result`. Reported from the BinaryExpression visit whenever `is_nan_identifier` matches an operand of an equality operator.","commonSituations":"Sanity checks after parseFloat/Number conversions (`if (Number(x) === NaN)` is a classic beginner bug); parsing JSON with missing numeric fields; porting formulas from spreadsheets or other languages into JavaScript.","solutions":["Use `Number.isNaN(value)` instead of comparing to NaN","Run `oxlint --fix` to auto-rewrite the comparison into an isNaN call","Add a unit test asserting the NaN path is actually reachable after the rewrite"],"exampleFix":"// before — always false, error handling never runs\nif (input === NaN) {\n  showError();\n}\n\n// after\nif (Number.isNaN(input)) {\n  showError();\n}","handlingStrategy":"validation","validationCode":"// .oxlintrc.json\n{ \"rules\": { \"use-isnan\": \"error\" } }\n// gate: npx oxlint --deny-warnings src/\n// grep guard: rg \"(===?|!==?)\\s*NaN|NaN\\s*(===?|!==?)\" src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat `=== NaN` as a review-blocking bug; teach Number.isNaN in onboarding","Keep the rule in the recommended/correctness set for all packages","Cover numeric parsing helpers with NaN-input tests","When porting validation code from other languages, re-check every NaN comparison"],"tags":["lint","oxlint","eslint","nan","correctness","floating-point","operators"],"backgroundTag":"nan-comparison","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}