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_text

View on GitHub (pinned to 15f3fe6b15)

Solutions

  1. Normalize the file's indentation (consistent 4-space indents) so the outer `if` has detectable indentation and rerun ruff
  2. Collapse the conditions manually into `if a and b:`
  3. 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

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


AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05). Data as JSON: /api/errors/0c0a83fe337261bb. Report an issue: GitHub.