oxc-project/oxc · error · OxcDiagnostic

Checking inequality with NaN will always return true

Error message

Checking inequality with NaN will always return true

What it means

oxlint's `use-isnan` rule (eslint plugin, correctness category) reports binary expressions where either operand is the bare identifier `NaN`. For the `!=`/`!==` arm of `comparison_with_nan` it emits this message because IEEE-754 NaN compares unequal to every value, including itself, so an inequality against NaN is constantly true and the guarded branch never behaves as written.

Solutions

  1. Rewrite the check as `!Number.isNaN(x)` (preferred) or `!isNaN(x)` when string coercion is intended
  2. Run `oxlint --fix`: the rule's conditional fixer rewrites equality-family comparisons with NaN into an isNaN call
  3. Search the codebase for NaN literals near comparison operators to fix every occurrence in one pass

Example fix

// before — always true, so the branch always runs
if (value !== NaN) {
  doWork();
}

// after
if (!Number.isNaN(value)) {
  doWork();
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "use-isnan": "error" } }

// run as a pre-commit gate
// npx oxlint --deny-warnings src/

Prevention

When it happens

Trigger: Any `!=` or `!==` expression with a literal NaN operand on either side, e.g. `x !== NaN` or `NaN != y`. The AstKind::BinaryExpression arm of Rule::run calls is_nan_identifier on both operands and reports whichever matches.

Common situations: Developers porting habits from Java/Python where `x != Double.NaN` looks plausible; copy-pasted input-validation code; refactors that introduce a NaN sentinel value; TypeScript code where the comparison still type-checks.

Related errors


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

Appendix: 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)