{"record":{"id":"28646ac0b373841c","repo":"astral-sh/ruff","slug":"expected-indented-block-to-have-at-least-one-state-28646a","errorCode":null,"errorMessage":"Expected indented block to have at least one statement","messagePattern":"Expected indented block to have at least one statement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs","lineNumber":50,"sourceCode":"    let module_text = if outer_indent.is_empty() {\n        contents.to_string()\n    } else {\n        format!(\"def f():{}{contents}\", stylist.line_ending().as_str())\n    };\n\n    // Parse the CST.\n    let mut tree = match_statement(&module_text)?;\n\n    let statement = if outer_indent.is_empty() {\n        &mut tree\n    } else {\n        let embedding = match_function_def(&mut tree)?;\n\n        let indented_block = match_indented_block(&mut embedding.body)?;\n        indented_block.indent = Some(outer_indent);\n\n        let Some(statement) = indented_block.body.first_mut() else {\n            bail!(\"Expected indented block to have at least one statement\")\n        };\n        statement\n    };\n\n    let outer_with = match_with(statement)?;\n\n    let With {\n        body: Suite::IndentedBlock(outer_body),\n        ..\n    } = outer_with\n    else {\n        bail!(\"Expected outer with to have indented body\")\n    };\n\n    let [Statement::Compound(CompoundStatement::With(inner_with))] = &mut *outer_body.body else {\n        bail!(\"Expected one inner with statement\");\n    };\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs#L32-L68","documentation":"This is an internal fix-generation failure in Ruff's SIM117 (multiple with statements) rule. The rule matched a function definition whose body is a single `with` block, but the indented block parsed as empty (no statements). Since there is no statement to descend into and merge, the autofix bails instead of producing a corrupt edit.","triggerScenarios":"The `fix_multiple_with_statements` fixer ran on code where `match_indented_block` returned an `IndentedBlock` whose `body` is empty — i.e. a `with` (or enclosing def) whose block has zero statements after matching. This occurs on syntactically degenerate or exotic trees (empty blocks, dedented constructs, or partial parses) rather than on normal nested-with code.","commonSituations":"Malformed or auto-generated code fed through `ruff --fix`, a syntax construct the rule's AST matching didn't anticipate, or running an unreleased Ruff build over a corpus of unusual Python files.","solutions":["Report the failing snippet to the Ruff project; this bail indicates the autofix matcher hit an unexpected AST shape","Remove or reformat the offending empty/oddly-indented block manually and re-run `ruff --fix`","Run with `--no-fix` or `--fix-only` disabled for that rule (ignore SIM117) to skip the fixer"],"exampleFix":"# before (empty block that breaks the fixer)\nwith open('a') as f:\n    pass\n# after\nwith open('a') as f:\n    handle(f)","handlingStrategy":"fallback","validationCode":"// Before relying on SIM117 autofix, verify each `with` body has at least one statement:\nimport ast\nfor node in ast.walk(ast.parse(src)):\n    if isinstance(node, ast.With) and not node.body:\n        print('empty with body at line', node.lineno)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure `with` blocks are non-empty before running `ruff --fix`","Avoid running autofix over partially parsed or generated code","Pin a released Ruff version and report fixer bails upstream"],"tags":["ruff","autofix","flake8-simplify","fixer"],"backgroundTag":"autofix-failed-to-apply","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}