astral-sh/ruff · info
Unable to fix multiline statement
Error message
Unable to fix multiline statement
What it means
`collapse_nested_if` first determines the indentation unit of the outer statement via `whitespace::indentation`; for a multiline or unindented context this returns `None`, so the SIM102 fix aborts early with this message. It exists to avoid producing a mis-indented merged `if`.
Source
Thrown at crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs:317
libcst_native::LeftParen::default(),
libcst_native::RightParen::default(),
)
}
libcst_native::Expression::IfExp(_)
| libcst_native::Expression::Lambda(_)
| libcst_native::Expression::NamedExpr(_) => expr.with_parens(
libcst_native::LeftParen::default(),
libcst_native::RightParen::default(),
),
_ => expr,
}
}
/// Convert `if a: if b:` to `if a and b:`.
fn collapse_nested_if(locator: &Locator, stylist: &Stylist, nested_if: NestedIf) -> Result<Edit> {
// Infer the indentation of the outer block.
let Some(outer_indent) = whitespace::indentation(locator.contents(), &nested_if) else {
bail!("Unable to fix multiline statement");
};
// Extract the module text.
let contents = locator.lines_str(nested_if.range());
// If this is an `elif`, we have to remove the `elif` keyword for now. (We'll
// restore the `el` later on.)
let module_text = if nested_if.is_elif() {
Cow::Owned(contents.replacen("elif", "if", 1))
} else {
Cow::Borrowed(contents)
};
// If the block is indented, "embed" it in a function definition, to preserve
// indentation while retaining valid source code. (We'll strip the prefix later
// on.)
let module_text = if outer_indent.is_empty() {
module_textView on GitHub (pinned to 15f3fe6b15)
Solutions
- Normalize the file's indentation (consistent 4-space indents) so the outer `if` has detectable indentation and rerun ruff
- Collapse the conditions manually into `if a and b:`
- Suppress with `# noqa: SIM102` if the nested form is intended
Defensive patterns
Strategy: validation
Validate before calling
# verify the file uses consistent 4-space indentation before running the fix python - <<'EOF' import sys src = open(sys.argv[1]).read() assert '\t' not in src, 'tabs found; normalize indentation first' EOF
Prevention
- Configure and run ruff format so indentation is uniform before lint fixes
- Keep multiline `if` headers parenthesized and conventionally indented
- Detect tab/space mixing in CI before applying autofixes
When it happens
Trigger: `ruff check --fix` on a nested `if` whose outer statement's indentation cannot be inferred — typically top-level compound statements in odd positions or multiline constructs that break the indentation heuristic.
Common situations: Files with tabs/spaces mixing, statements at module level without surrounding block indentation, or heavily formatted multiline `if` headers.
Related errors
- Failed to collapse `if`: {err}
- Expected indented block to have at least one statement
- Expected outer if to have indented body and no else
- Expected one inner if statement
- Failed to collapse `with`: {err}
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05).
Data as JSON: /api/errors/0c0a83fe337261bb.
Report an issue: GitHub.