{"record":{"id":"9313d0e4408cdb37","repo":"oxc-project/oxc","slug":"unexpected-re-assignment-of-const-variable-name","errorCode":null,"errorMessage":"Unexpected re-assignment of `const` variable {name}.","messagePattern":"Unexpected re-assignment of `const` variable (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/oxc_linter/src/rules/eslint/no_const_assign.rs","lineNumber":11,"sourceCode":"use oxc_ast::AstKind;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_ecmascript::BoundNames;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::{AstNode, SymbolId};\nuse oxc_span::Span;\n\nuse crate::{ast_util::variable_declaration_kind, context::LintContext, rule::Rule};\n\nfn no_const_assign_diagnostic(name: &str, decl_span: Span, assign_span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"Unexpected re-assignment of `const` variable {name}.\"))\n        .with_help(\"Use `let` instead of `const` if you need to reassign this variable.\")\n        .with_labels([\n            decl_span.label(format!(\"{name} is declared here as `const`.\")),\n            assign_span.label(format!(\"{name} is re-assigned here.\")),\n        ])\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoConstAssign;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow reassigning `const` variables.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// We cannot modify variables that are declared using the `const` keyword,","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_const_assign.rs#L1-L29","documentation":"Diagnostic from the oxlint rule `no-const-assign` (crates/oxc_linter/src/rules/eslint/no_const_assign.rs). It fires when a variable declared with `const` is later the target of an assignment (including compound assignment, increment/decrement, and for-in/for-of assignment targets). The diagnostic is two-label: `'{name} is declared here as const.'` plus `'{name} is re-assigned here.'`. At runtime this throws `TypeError: Assignment to constant variable`, so the rule is correctness-critical.","triggerScenarios":"An AssignmentExpression / UpdateExpression / ForIn-Of target Reference whose SymbolId resolves to a declaration with `const` kind (checked via `variable_declaration_kind` over bound names) — e.g. `const x = 1; x = 2;`, `x += 1;`, `x++;`, `for (x of ys)` when x is const.","commonSituations":"Refactoring `let` to `const` for 'prefer-const' and missing a later mutation; adding retry/reset logic (`count = 0`) to a const accumulator; destructured `const {a} = obj` later reassigned; this always hard-crashes in strict-mode ESM, so the lint report precedes a real runtime TypeError.","solutions":["Change the declaration from `const` to `let` if reassignment is intended: `let x = 1; x = 2;`.","If immutability is intended, change the reassignment into a mutation (for objects/arrays: `items.push(...)` instead of `items = [...]`) or use a new binding.","For accumulators, restructure with `reduce` or a mutable local so the const stays const.","Never widen to `var` — that hides rather than fixes the mutation."],"exampleFix":"// before\nconst total = 0;\nfor (const n of nums) {\n  total += n; // TypeError: Assignment to constant variable\n}\n\n// after\nlet total = 0;\nfor (const n of nums) {\n  total += n;\n}","handlingStrategy":"validation","validationCode":"// Prefer the AST-based rule; textual heuristic for hooks:\nconst decls = [...src.matchAll(/\\bconst\\s+(\\w+)/g)].map(m => m[1]);\nconst reassigned = decls.filter(n => new RegExp(`\\\\b${n}\\\\s*(=[^=]|\\\\+\\+|--|\\\\*=|\\\\+=)`).test(src));","typeGuard":null,"tryCatchPattern":"// Wrap risky third-party-driven mutation if you cannot lint it:\ntry { moduleHotReload(); } catch (e) {\n  if (e instanceof TypeError && /Assignment to constant variable/.test(e.message)) {\n    reportConstReassignment(e);\n  } else throw e;\n}","preventionTips":["Let prefer-const and no-const-assign run together in CI so the pair stays consistent.","When converting let to const, search for all writes to the binding first.","Prefer mutating container contents (push/spread) over rebinding."],"tags":["lint","const","assignment","runtime-error","oxlint"],"backgroundTag":"const-reassignment","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}