{"record":{"id":"159a48b9f30c4ae0","repo":"oxc-project/oxc","slug":"name-is-not-modified-in-this-loop","errorCode":null,"errorMessage":"'{name}' is not modified in this loop.","messagePattern":"'(.+?)' is not modified in this loop\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/no_unmodified_loop_condition.rs","lineNumber":17,"sourceCode":"use rustc_hash::{FxHashMap, FxHashSet};\n\nuse oxc_allocator::GetAddress;\nuse oxc_ast::{\n    AstKind,\n    ast::{Expression, IdentifierReference},\n};\nuse oxc_ast_visit::{VisitJs, walk_js};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::{NodeId, Reference, SymbolId};\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_unmodified_loop_condition_diagnostic(name: &str, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"'{name}' is not modified in this loop.\")).with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoUnmodifiedLoopCondition;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow references in loop conditions that are never modified within the loop.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// A loop condition that depends on values that never change within the loop body\n    /// can cause infinite loops or logic bugs.\n    ///\n    /// ### Examples\n    ///\n    /// Examples of **incorrect** code for this rule:","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_unmodified_loop_condition.rs#L1-L35","documentation":"`no-unmodified-loop-condition` reports loop conditions (`while`/`do-while`, and `for` test expressions) that reference variables which are never modified inside the loop body — meaning the loop either never runs, runs exactly one iteration via break, or never terminates. The message names the stale variable and carries only a label, no help text. Like ESLint's version it is heuristic: modifications hidden behind closures, `await` side effects, or `in` operator checks can be missed, and it may also produce false positives when the loop body intentionally mutates via called functions (the rule tries to account for some of this by tracking references).","triggerScenarios":"`while (node) { doSomething(node); }` where nothing assigns `node` — the reference in the condition resolves to a symbol with no writes inside the body; also `for (; queue.length;)` when the body never pops the queue.","commonSituations":"Forgetting the advancing statement (`node = node.next`, `i++`) when hand-rolling traversal; condition variables mutated only inside a helper function called from the loop; while-poll loops waiting on external state that never changes locally.","solutions":["Add the missing mutation inside the loop (`node = node.next;`).","If mutation happens via a helper, make it explicit in the loop (return the next value and assign it).","If the loop is intentionally infinite (`while (true)` with internal breaks), rewrite the condition as `true` so the rule stops tracking the variable.","For polling on external state, restructure with events/async primitives instead of a spin loop."],"exampleFix":"// before\nwhile (current) {\n  visit(current);\n}\n\n// after\nwhile (current) {\n  visit(current);\n  current = current.next;\n}","handlingStrategy":"validation","validationCode":"// self-check for hand-rolled traversals: assert the cursor advances\nfunction walkSafe(node) {\n  let cur = node;\n  let steps = 0;\n  while (cur) {\n    visit(cur);\n    cur = cur.next;\n    if (++steps > 1e6) throw new Error('loop condition never modified: runaway traversal');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Double-check every while/for you write names the variable it mutates in the body.","Prefer for...of / iterator protocols over manual cursor loops where possible.","Treat this diagnostic as an infinite-loop candidate, not a style nit."],"tags":["eslint","oxlint","no-unmodified-loop-condition","loops","infinite-loop","control-flow"],"backgroundTag":"unmodified-loop-condition","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}