{"record":{"id":"56b15e63c30a8943","repo":"oxc-project/oxc","slug":"unnecessary-else-after-return","errorCode":null,"errorMessage":"Unnecessary `else` after `return`.","messagePattern":"Unnecessary `else` after `return`\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_else_return.rs","lineNumber":18,"sourceCode":"use schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse oxc_ast::{AstKind, ast::Statement};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::ScopeId;\nuse oxc_span::{GetSpan, Span};\nuse oxc_syntax::line_terminator::is_line_terminator;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_else_return_diagnostic(else_keyword: Span, last_return: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unnecessary `else` after `return`.\")\n        .with_labels([\n            last_return.label(\"This consequent block always returns,\"),\n            else_keyword.primary_label(\"Making this `else` block unnecessary.\"),\n        ])\n        .with_help(\"Remove the `else` block, moving its contents outside of the `if` statement.\")\n}\n\n#[derive(Debug, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoElseReturn {\n    /// Whether to allow `else if` blocks after a return statement.\n    ///\n    /// Examples of **incorrect** code for this rule with `allowElseIf: false`:\n    /// ```javascript\n    /// function foo() {\n    ///     if (error) {\n    ///         return 'It failed';\n    ///     } else if (loading) {","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_else_return.rs#L1-L36","documentation":"This diagnostic comes from the `no_else_return` rule in oxlint. It reports an `else` block that follows an `if` block whose last statement returns. The `else` adds nothing: without it, the code runs the same way. The rule option `allowElseIf` defaults to `true`, so an `else if` chain after a return stays allowed until you set it to `false`.","triggerScenarios":"An `if` consequent that ends with a `return`, followed by a plain `else` block: `if (ok) { return 1; } else { doWork(); }`. With `allowElseIf: false`, a following `else if` is also reported.","commonSituations":"A guard-clause refactor leaves the old `else` behind. Developers trained to always pair `if` with `else`. A team adopts oxlint and existing code lights up in CI.","solutions":["Delete the `else` keyword and dedent its block.","Set `\"allowElseIf\": false` in the rule config when `else if` after a return should also be flagged.","Disable the rule for the file with an `oxlint-disable` comment when the current shape is the team style."],"exampleFix":"// before\nfunction check(x) {\n  if (x < 0) {\n    return 'neg';\n  } else {\n    log(x);\n    return 'pos';\n  }\n}\n\n// after\nfunction check(x) {\n  if (x < 0) {\n    return 'neg';\n  }\n  log(x);\n  return 'pos';\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use guard clauses: return early and keep the main path flat.","Remove the `else` in the same edit that adds an early return.","Fix the `allowElseIf` setting once, to match the team style."],"tags":["javascript","eslint","lint","style","control-flow"],"backgroundTag":"lint-unnecessary-else","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"}