astral-sh/ruff · error
Expected indented block to have at least one statement
Error message
Expected indented block to have at least one statement
What it means
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.
Source
Thrown at crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs:50
let module_text = if outer_indent.is_empty() {
contents.to_string()
} else {
format!("def f():{}{contents}", stylist.line_ending().as_str())
};
// Parse the CST.
let mut tree = match_statement(&module_text)?;
let statement = if outer_indent.is_empty() {
&mut tree
} else {
let embedding = match_function_def(&mut tree)?;
let indented_block = match_indented_block(&mut embedding.body)?;
indented_block.indent = Some(outer_indent);
let Some(statement) = indented_block.body.first_mut() else {
bail!("Expected indented block to have at least one statement")
};
statement
};
let outer_with = match_with(statement)?;
let With {
body: Suite::IndentedBlock(outer_body),
..
} = outer_with
else {
bail!("Expected outer with to have indented body")
};
let [Statement::Compound(CompoundStatement::With(inner_with))] = &mut *outer_body.body else {
bail!("Expected one inner with statement");
};
View on GitHub (pinned to 26f38c119c)
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
Example fix
# before (empty block that breaks the fixer)
with open('a') as f:
pass
# after
with open('a') as f:
handle(f) Defensive patterns
Strategy: fallback
Validate before calling
// Before relying on SIM117 autofix, verify each `with` body has at least one statement:
import ast
for node in ast.walk(ast.parse(src)):
if isinstance(node, ast.With) and not node.body:
print('empty with body at line', node.lineno) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expected outer with to have indented body
- Expected one inner with statement
- Failed to collapse `with`: {err}
- Unable to fix multiline statement
- Expected colon after test
AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05).
Data as JSON: /api/errors/28646ac0b373841c.
Report an issue: GitHub.