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.
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
- Rewrite the check as `!Number.isNaN(x)` (preferred) or `!isNaN(x)` when string coercion is intended
- Run `oxlint --fix`: the rule's conditional fixer rewrites equality-family comparisons with NaN into an isNaN call
- 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
- Review for the Number.isNaN idiom; raw NaN comparisons should never merge
- Keep the eslint correctness category enabled in oxlint so use-isnan is always on
- Add a grep guard in CI: rg "(===?|!==?)\s*NaN|NaN\s*(===?|!==?)" src/
- Unit-test NaN paths so rewrites stay behaviorally correct
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
- Checking equality with NaN will always return false
- Comparison with NaN will always return false
- Checking `switch` discriminant against NaN will never match
- Checking for NaN in `case` clause will never match
- NaN values will never be found by `Array.prototype.{method_n
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9d74b99e6b2b1434.
Report an issue: GitHub.