{"record":{"id":"3ede237f515c4a92","repo":"oxc-project/oxc","slug":"ident-name-is-always-undefined-because-it-s","errorCode":null,"errorMessage":"'{ident_name}' is always 'undefined' because it's never assigned.","messagePattern":"'(.+?)' is always 'undefined' because it's never assigned\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_unassigned_vars.rs","lineNumber":9,"sourceCode":"use oxc_ast::{AstKind, ast::BindingPattern};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_unassigned_vars_diagnostic(span: Span, ident_name: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\n        \"'{ident_name}' is always 'undefined' because it's never assigned.\",\n    ))\n    .with_help(\n        \"Variable declared without assignment. Either assign a value or remove the declaration.\",\n    )\n    .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoUnassignedVars;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow let or var variables that are read but never assigned.\n    ///\n    /// #### Ignored Files\n    /// This rule ignores `.svelte` and `.vue` files entirely. Oxlint only parses the","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/oxc-project/oxc/blob/a3d33dda7cb69da23db4fcaa2c0c05de61e760a1/crates/oxc_linter/src/rules/eslint/no_unassigned_vars.rs#L1-L27","documentation":"`no-unassigned-vars` reports `let`/`var` declarations that are never assigned anywhere in the program — the symbol is read but always evaluates to `undefined`. The diagnostic interpolates the identifier name: `'{ident_name}' is always 'undefined' because it's never assigned.` It targets declarations that look like they should carry a value (dead intent) rather than intentional undefined sentinels.","triggerScenarios":"`let total;` followed by reads of `total` but no assignment (`total = ...`) anywhere; declarations left behind after deleting the code that computed them.","commonSituations":"Deleting an initialization during a refactor and leaving the declaration; copy-paste scaffolding (`let result, data, err;`); migrating from `var` hoisting patterns where values were assigned conditionally and one branch was removed.","solutions":["Restore or add the assignment the reads expect: `let total = 0;`.","If the variable is dead, delete the declaration (and its reads — they are now dead too).","If undefined-on-purpose is intended, make it explicit and reviewable: `let cached = undefined;` reads as intentional, or restructure to return/param passing."],"exampleFix":"// before\nlet total;\nconsole.log(`total: ${total}`); // always undefined\n\n// after\nlet total = 0;\nconsole.log(`total: ${total}`);","handlingStrategy":"validation","validationCode":"# find never-assigned declarations textually (heuristic)\nrg -n '^\\s*(let|var)\\s+[A-Za-z_$][\\w$]*\\s*;' src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Initialize declarations at the point of declaration.","After deleting an assignment during refactor, delete the declaration too.","Let TypeScript's 'used before assigned' checks cover typed files."],"tags":["eslint","oxlint","no-unassigned-vars","variables","undefined","dead-code"],"backgroundTag":"uninitialized-variable","analyzedSha":"a3d33dda7cb69da23db4fcaa2c0c05de61e760a1","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}