{"record":{"id":"da41eb63299b9412","repo":"astral-sh/ruff","slug":"expected-one-inner-if-statement","errorCode":null,"errorMessage":"Expected one inner if statement","messagePattern":"Expected one inner if statement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs","lineNumber":377,"sourceCode":"\n    let outer_if = match_if(statement)?;\n\n    let libcst_native::If {\n        body: libcst_native::Suite::IndentedBlock(outer_body),\n        orelse: None,\n        ..\n    } = outer_if\n    else {\n        bail!(\"Expected outer if to have indented body and no else\")\n    };\n\n    let [\n        libcst_native::Statement::Compound(libcst_native::CompoundStatement::If(\n            inner_if @ libcst_native::If { orelse: None, .. },\n        )),\n    ] = &mut *outer_body.body\n    else {\n        bail!(\"Expected one inner if statement\");\n    };\n\n    outer_if.test =\n        libcst_native::Expression::BooleanOperation(Box::new(libcst_native::BooleanOperation {\n            left: Box::new(parenthesize_and_operand(outer_if.test.clone())),\n            operator: libcst_native::BooleanOp::And {\n                whitespace_before: space(),\n                whitespace_after: space(),\n            },\n            right: Box::new(parenthesize_and_operand(inner_if.test.clone())),\n            lpar: vec![],\n            rpar: vec![],\n        }));\n    outer_if.body = inner_if.body.clone();\n\n    // Reconstruct and reformat the code.\n    let module_text = tree.codegen_stylist(stylist);\n    let module_text = if outer_indent.is_empty() {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs#L359-L395","documentation":"After matching the outer `if`, the collapse requires its indented body to contain exactly one statement and that statement to be a plain `if` without `orelse`. Anything else (multiple statements, an `elif`/`else` on the inner node, other compound statements) bails with this message, since `if a: if b:` can only merge when the inner body is a single guard `if`.","triggerScenarios":"`ruff check --fix` on an outer `if` whose body holds several statements before/after the inner `if`, or the inner `if` has its own `else`/`elif`.","commonSituations":"Nested guards with trailing statements (`if a: x = 1; if b: ...` on separate lines), inner `if` with `else`, bodies mixing simple and compound statements.","solutions":["Move any extra statements out of the outer body (or merge them into the innermost block) so only the inner `if` remains, then rerun the fix","Manually combine conditions into `if a and b:` when restructuring by hand","Add `# noqa: SIM102` if the multi-statement nesting is intentional"],"exampleFix":"// before\nif a:\n    setup()\n    if b:\n        do()\n// after\nsetup_ok = not a or False  # or restructure:\nif a and b:\n    do()","handlingStrategy":"validation","validationCode":"python - <<'EOF'\nimport ast, sys\ntree = ast.parse(open(sys.argv[1]).read())\nfor n in ast.walk(tree):\n    if isinstance(n, ast.If) and len(n.body) == 1 and isinstance(n.body[0], ast.If):\n        inner = n.body[0]\n        if not (len(inner.body) >= 1 and not inner.orelse) or not n.orelse:\n            pass\n        if inner.orelse or len(n.body) != 1:\n            print('not a single plain inner if at line', inner.lineno)\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the outer block containing exactly the inner `if` when you intend a collapsible guard","Move side-effect statements out of the outer guard body","Use `# noqa: SIM102` for deliberate multi-statement nesting instead of expecting a fix"],"tags":["ruff","flake8-simplify","sim102","autofix"],"backgroundTag":"linter-autofix-skipped","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}