{"record":{"id":"9d6241cf2d96a222","repo":"oxc-project/oxc","slug":"checking-for-nan-in-case-clause-will-never-match","errorCode":null,"errorMessage":"Checking for NaN in `case` clause will never match","messagePattern":"Checking for NaN in `case` clause will never match","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/use_isnan.rs","lineNumber":40,"sourceCode":"        }\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!(\n        \"NaN values will never be found by `Array.prototype.{method_name}`\"\n    ))\n    .with_help(\"Use the `isNaN` function to check for NaN values.\")\n    .with_label(span)\n}\n\n#[derive(Debug, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct UseIsnan {\n    /// Whether to disallow NaN in switch cases and discriminants\n    enforce_for_switch_case: bool,\n    /// Whether to disallow NaN as arguments of `indexOf` and `lastIndexOf`","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/use_isnan.rs#L22-L58","documentation":"The case-clause variant of use-isnan's switch checking (on by default): a `case NaN:` test never matches because switch case matching uses `===` and NaN is not equal to itself, leaving the case body unreachable no matter what the discriminant evaluates to.","triggerScenarios":"`switch (value) { case NaN: handleBad(); break; default: ... }` — any SwitchCase whose test expression is the identifier NaN, while `enforce_for_switch_case` is enabled.","commonSituations":"Validation code trying to route NaN inputs through a switch; porting if/else chains that already contained the broken `=== NaN` check; table-driven parsers handling missing numeric fields.","solutions":["Hoist the NaN test before the switch: `if (Number.isNaN(value)) { ... } else switch (value) { ... }`","Delete the case if it was dead on purpose","Keep `enforceForSwitchCase` at its default true so regressions keep being caught"],"exampleFix":"// before — case NaN is unreachable\nswitch (value) {\n  case NaN:\n    handleInvalid();\n    break;\n  default:\n    handleValid();\n}\n\n// after\nif (Number.isNaN(value)) {\n  handleInvalid();\n} else {\n  handleValid();\n}","handlingStrategy":"validation","validationCode":"// .oxlintrc.json\n{ \"rules\": { \"use-isnan\": \"error\" } }\n// CI gate: npx oxlint --deny-warnings src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Route NaN handling through an if/Number.isNaN guard, never a case clause","When converting if/else chains to switch, drop any broken `=== NaN` branch first","Keep enforceForSwitchCase at its default true","Test dispatch code with NaN-valued inputs"],"tags":["lint","oxlint","eslint","nan","correctness","switch","control-flow"],"backgroundTag":"nan-comparison","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}