oxc-project/oxc · error · OxcDiagnostic

The update clause in this loop moves the variable in the wro

Error message

The update clause in this loop moves the variable in the wrong direction

What it means

Oxlint's port of the ESLint rule for-direction (crates/oxc_linter/src/rules/eslint/for_direction.rs:19). It compares the direction implied by the loop test with the effect of the update clause: when the update moves the counter away from satisfying the test (test `i < n` with `i--`, or `i > n` with `i++`, including `+=`/`-=` of the wrong sign), the loop either never runs or never terminates. Two labels tie the test ('This test moves in the wrong direction') to the update ('with this update'), and the help suggests a `while` loop for intentional infinite loops.

Source

Thrown at crates/oxc_linter/src/rules/eslint/for_direction.rs:20

    AstKind,
    ast::{
        AssignmentExpression, AssignmentTarget, Expression, IdentifierReference,
        SimpleAssignmentTarget,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_syntax::{
    operator::BinaryOperator::{GreaterEqualThan, GreaterThan, LessEqualThan, LessThan},
    operator::{AssignmentOperator, BinaryOperator, UnaryOperator, UpdateOperator},
};

use crate::fixer::{RuleFix, RuleFixer};
use crate::{AstNode, context::LintContext, rule::Rule};

fn for_direction_diagnostic(test_span: Span, update_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("The update clause in this loop moves the variable in the wrong direction")
        .with_help("Use `while` loop for intended infinite loop")
        .with_labels([
            test_span.label("This test moves in the wrong direction"),
            update_span.label("with this update"),
        ])
}

#[derive(Debug, Default, Clone)]
pub struct ForDirection;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow `for` loops where the update clause moves the counter in the wrong
    /// direction, preventing the loop from reaching its stop condition.
    ///
    /// ### Why is this bad?
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Fix the update so it moves toward the test boundary (`i++` with `i < n`, `i--` with `i > n`).
  2. If the infinite loop is intentional, write `while (true)` with a `break` so the intent is explicit.
  3. Re-check the test operator — sometimes the update is correct and the condition was inverted.

Example fix

// before (never terminates)
for (let i = 0; i < items.length; i--) {
  handle(items[i]);
}

// after
for (let i = 0; i < items.length; i++) {
  handle(items[i]);
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{
  "rules": {
    "for-direction": "error"
  }
}

Prevention

When it happens

Trigger: `for (let i = 0; i < 10; i--) {}`, `for (let j = n; j > 0; j++) {}`, or assignment updates like `i -= 1` against an upper-bound test.

Common situations: Flipping iteration direction while editing a loop; copy-pasting a countdown loop and changing only the condition; signed step values that go negative against a `<` test.

Related errors


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