{"record":{"id":"f8002dc45b74c3fa","repo":"oxc-project/oxc","slug":"unexpected-if-as-the-only-statement-in-a-if-bl","errorCode":null,"errorMessage":"Unexpected `if` as the only statement in a `if` block without `else`.","messagePattern":"Unexpected `if` as the only statement in a `if` block without `else`\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"info","filePath":"crates/oxc_linter/src/rules/unicorn/no_lonely_if.rs","lineNumber":9,"sourceCode":"use oxc_ast::AstKind;\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_lonely_if_diagnostic(if_stmt_span: Span, parent_if_stmt_span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected `if` as the only statement in a `if` block without `else`.\")\n        .with_help(\"Move the inner `if` test to the outer `if` test.\")\n        .with_labels([if_stmt_span, parent_if_stmt_span])\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoLonelyIf;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow `if` statements as the only statement in `if` blocks without `else`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It can be confusing to have an `if` statement without an `else` clause as the only statement in an `if` block.\n    ///\n    /// ### Examples\n    ///","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/no_lonely_if.rs#L1-L27","documentation":"Diagnostic from the oxlint rule `unicorn/no-lonely-if`. When an `if` block without an `else` contains exactly one statement and that statement is another `if`, the nesting reads like a forgotten case or a half-finished merge. The rule wants the tests joined into a single condition or the guards flattened with early returns. Purely stylistic — the control flow is equivalent.","triggerScenarios":"`if (user) { if (user.isActive) { grant(user); } }` — the inner `if` is the sole statement of the outer `if`'s consequent, and the outer `if` has no `else`. Both spans are labeled in the diagnostic.","commonSituations":"Guards layered on one refactor at a time; feature flags nested inside conditionals; merge artifacts where a second check got wrapped instead of combined with `&&`.","solutions":["Merge the conditions: `if (user && user.isActive)` or with optional chaining `if (user?.isActive)`","Prefer early returns/continue to keep guard clauses flat","When the inner test is intentionally a separate documented stage, suppress with `// oxlint-disable-next-line unicorn/no-lonely-if`"],"exampleFix":"// before\nif (user) {\n  if (user.isActive) {\n    grant(user);\n  }\n}\n\n// after\nif (user?.isActive) {\n  grant(user);\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Combine nested guards into `&&` conditions or early returns as you write them","Watch for lonely ifs appearing after feature-flag removal","Remember the rule only fires when the outer if has no else block"],"tags":["control-flow","style","readability","oxlint"],"backgroundTag":"lonely-if","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"}