oxc-project/oxc · error · OxcDiagnostic

Checking for NaN in `case` clause will never match

Error message

Checking for NaN in `case` clause will never match

What it means

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.

Source

Thrown at crates/oxc_linter/src/rules/eslint/use_isnan.rs:40

        }
        BinaryOperator::Equality | BinaryOperator::StrictEquality => {
            "Checking equality with NaN will always return false"
        }
        _ => "Comparison with NaN will always return false",
    };
    OxcDiagnostic::warn(msg)
        .with_help("Use the `isNaN` function to compare with NaN.")
        .with_label(span)
}

fn switch_nan(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Checking `switch` discriminant against NaN will never match")
        .with_help("Use the `isNaN` function instead of the switch.")
        .with_label(span)
}

fn case_nan(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Checking for NaN in `case` clause will never match")
        .with_help("Use the `isNaN` function instead of the switch.")
        .with_label(span)
}

fn index_of_nan(method_name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "NaN values will never be found by `Array.prototype.{method_name}`"
    ))
    .with_help("Use the `isNaN` function to check for NaN values.")
    .with_label(span)
}

#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct UseIsnan {
    /// Whether to disallow NaN in switch cases and discriminants
    enforce_for_switch_case: bool,
    /// Whether to disallow NaN as arguments of `indexOf` and `lastIndexOf`

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Hoist the NaN test before the switch: `if (Number.isNaN(value)) { ... } else switch (value) { ... }`
  2. Delete the case if it was dead on purpose
  3. Keep `enforceForSwitchCase` at its default true so regressions keep being caught

Example fix

// before — case NaN is unreachable
switch (value) {
  case NaN:
    handleInvalid();
    break;
  default:
    handleValid();
}

// after
if (Number.isNaN(value)) {
  handleInvalid();
} else {
  handleValid();
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "use-isnan": "error" } }
// CI gate: npx oxlint --deny-warnings src/

Prevention

When it happens

Trigger: `switch (value) { case NaN: handleBad(); break; default: ... }` — any SwitchCase whose test expression is the identifier NaN, while `enforce_for_switch_case` is enabled.

Common situations: 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.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/9d6241cf2d96a222. Report an issue: GitHub.