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
- Remove the dead branch, or replace it with an explicit `Number.isNaN(x)` guard if NaN handling was the intent
- Restructure range checks to test NaN first: `if (Number.isNaN(x)) ... else if (x < limit) ...`
- 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
- Check Number.isNaN(x) before any range comparison on possibly-NaN values
- Remember relational NaN comparisons are silent dead code — only the linter sees them
- Property-test numeric helpers with NaN inputs
- Grep new code for NaN literals used as comparators
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
- Checking inequality with NaN will always return true
- Checking equality 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/492c102169392058.
Report an issue: GitHub.