oxc-project/oxc · warning

Unexpected constant condition

Error message

Unexpected constant condition

What it means

Diagnostic from the oxlint rule `no-constant-condition` (crates/oxc_linter/src/rules/eslint/no_constant_condition.rs). It fires when the test of an `if`, ternary, `while`, `do-while`, or `for` is a constant expression (literal, constant arithmetic, always-truthy object, `x ||= true`, etc.), labeled 'this expression will always evaluate to the same value'. Loop tests are governed by the `checkLoops` option: default `allExceptWhileTrue` keeps plain `while (true)` legal; `all`/`true` reports it; `none`/`false` skips loop tests entirely (with extra generator/yield-aware handling for loops that yield).

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_constant_condition.rs:22

use oxc_ast::{
    AstKind,
    ast::{ArrowFunctionExpression, Expression, Function, YieldExpression},
};
use oxc_ast_visit::VisitJs;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_syntax::{node::NodeId, scope::ScopeFlags};

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

fn no_constant_condition_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected constant condition")
        .with_help("Update the condition to not be constant, or remove the condition entirely")
        .with_label(span.label("this expression will always evaluate to the same value"))
}

#[derive(Debug, Default, Clone, PartialEq, JsonSchema, Serialize)]
#[serde(rename_all = "camelCase")]
enum CheckLoops {
    All,
    #[default]
    AllExceptWhileTrue,
    None,
}

impl<'de> Deserialize<'de> for CheckLoops {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace the constant test with the real condition it was placeholder for.
  2. If the branch is dead, delete it (or gate it behind a named constant read from config so it is no longer statically constant).
  3. For intentional `while (true)` loops keep the default `checkLoops: "allExceptWhileTrue"`, or set it explicitly in .oxlintrc.json if your config was tightened to `all`.
  4. For deliberate constant tests (spec tests, benchmarks), suppress with `// oxlint-disable-next-line no-constant-condition`.

Example fix

// before
if (false) {
  doSomethingUnfinished();
}
while (true) { poll(); }

// after
if (!featureEnabled) {
  doSomethingUnfinished();
}
for (;;) { poll(); } // or keep checkLoops at "allExceptWhileTrue"
Defensive patterns

Strategy: validation

Validate before calling

// Gate: constant tests in conditions (heuristic; rule handles folding)
const constantTest = /\b(if|while)\s*\(\s*(true|false|null|undefined|\d+|['"][^'"]*['"])\s*\)/.test(src);

Prevention

When it happens

Trigger: `if (false) {...}`, `if (new Boolean(x)) {...}`, `x ? a : b` where x is a constant, `do {...} while (x = -1)`; plus `while (true)` only when checkLoops is `all`/`true`. Constants are computed with the shared IsConstant utility, so constant-foldable expressions and always-truthy boxed booleans count.

Common situations: Dead feature-flag branches left from `if (false)` debugging; placeholder conditions before wiring real inputs; infinite `while (true)` server loops tripping after someone sets `checkLoops: true`; ternaries over `typeof x === 'undefined'` styles that fold to constants.

Related errors


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