oxc-project/oxc · error · OxcDiagnostic

Comparison with NaN will always return false

Error message

Comparison with NaN will always return false

What it means

The relational arm (the match's `_` branch covering `<`, `<=`, `>`, `>=`) of oxlint's `use-isnan` rule: every ordering comparison involving NaN evaluates to false, because NaN is unordered relative to all numbers including itself. The flagged condition is dead code.

Source

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

use serde::Deserialize;

use crate::{
    AstNode,
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
};

fn comparison_with_nan(span: Span, operator: BinaryOperator) -> OxcDiagnostic {
    let msg = match operator {
        BinaryOperator::Inequality | BinaryOperator::StrictInequality => {
            "Checking inequality with NaN will always return true"
        }
        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!(

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Remove the dead branch, or replace it with an explicit `Number.isNaN(x)` guard if NaN handling was the intent
  2. Restructure range checks to test NaN first: `if (Number.isNaN(x)) ... else if (x < limit) ...`
  3. Run oxlint across the project to find every relational NaN comparison

Example fix

// before — always false, clamp() is unreachable
if (value < NaN) {
  clamp(value);
}

// after — express the real intent explicitly
if (Number.isNaN(value)) {
  clamp(value);
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "use-isnan": "error" } }
// CI gate: npx oxlint --deny-warnings .
// grep guard for relational NaN: rg "[<>]=?\s*NaN|NaN\s*[<>]" src/

Prevention

When it happens

Trigger: Binary relational expressions with a NaN operand: `x < NaN`, `NaN >= limit`. Reported whenever `is_nan_identifier` matches either side of a non-equality comparison operator.

Common situations: Range checks written against values that may be NaN; porting math code that assumed NaN sorts like -Infinity; refactors that replaced a variable with the NaN literal.

Related errors


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