{"record":{"id":"77f0b64636a99335","repo":"oxc-project/oxc","slug":"unexpected-lexical-declaration-in-case-block","errorCode":null,"errorMessage":"Unexpected lexical declaration in case block.","messagePattern":"Unexpected lexical declaration in case block\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/no_case_declarations.rs","lineNumber":12,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Statement, SwitchCase, VariableDeclarationKind},\n};\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_case_declarations_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected lexical declaration in case block.\")\n        .with_help(\"Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoCaseDeclarations;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow lexical declarations in case clauses.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The reason is that the lexical declaration is visible\n    /// in the entire switch block but it only gets initialized when it is assigned,\n    /// which will only happen if the case where it is defined is reached.\n    ///","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_case_declarations.rs#L1-L30","documentation":"Diagnostic from the oxlint rule `no-case-declarations` (crates/oxc_linter/src/rules/eslint/no_case_declarations.rs). It fires when a lexical declaration (`let`, `const`, `class`, or `function` declaration) appears directly in a `switch` case clause without a block. All clauses of one switch share a single block scope, so a lexical declaration in one case is visible (and collides) across every other case in the same switch, which easily produces SyntaxErrors or surprising temporal-dead-zone behavior.","triggerScenarios":"A SwitchCase whose consecutive statements include a VariableDeclaration with kind `let`/`const` (or class/function declaration) and are not wrapped in a BlockStatement — e.g. `switch (x) { case 1: let a = 1; break; case 2: let a = 2; }`.","commonSituations":"Adding a new case with `const` to an existing switch; duplicated variable names across cases (classic `SyntaxError: Identifier 'a' has already been declared` at runtime); refactoring if/else chains into switches during lint adoption.","solutions":["Wrap the offending case body in braces: `case 1: { const a = 1; break; }` — this is exactly what the diagnostic's help text recommends.","Alternatively, declare the variable once before the switch and assign in each case.","If only one branch needs local state, extract that branch into a function called from the case.","Keep the practice of always bracing multi-statement cases to prevent recurrence."],"exampleFix":"// before\nswitch (kind) {\n  case 'a':\n    const map = { x: 1 };\n    break;\n  case 'b':\n    const map2 = { x: 2 };\n    break;\n}\n\n// after\nswitch (kind) {\n  case 'a': {\n    const map = { x: 1 };\n    break;\n  }\n  case 'b': {\n    const map2 = { x: 2 };\n    break;\n  }\n}","handlingStrategy":"validation","validationCode":"// Quick gate: lexical declarations directly inside a case clause\nfunction caseHasBareLexical(stmts) {\n  return stmts.some(s => /^(let|const|class|function)\\b/.test(s.source || ''));\n}\n// better: let oxlint's AST-based check run in a pre-commit hook","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always brace multi-statement case bodies.","Enable editor format-on-save with a formatter that keeps the braces.","Declare switch-scoped variables once above the switch, not inside cases."],"tags":["lint","switch","scope","lexical-declaration","oxlint"],"backgroundTag":"lexical-declaration-in-switch-case","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"}