astral-sh/ruff · info
Failed to collapse `if`: {err}
Error message
Failed to collapse `if`: {err} What it means
Rule SIM102 (collapsible nested `if`) attempts to rewrite `if a: if b:` into `if a and b:` using a libcst-native transformer; if that transformer returns an error, the check bails with this message wrapping the inner error. The diagnostic remains, only the autofix is lost.
Source
Thrown at crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs:163
(&nested_if).into(),
checker.locator(),
checker.settings().pycodestyle.max_line_length,
checker.settings().tab_size,
)
}) {
Ok(Some(Fix::applicable_edit(
edit,
if is_collapsible_if_fix_safe_enabled(checker.settings()) {
Safe
} else {
Unsafe
},
)))
} else {
Ok(None)
}
}
Err(err) => bail!("Failed to collapse `if`: {err}"),
}
});
}
}
#[derive(Debug, Clone, Copy)]
pub(super) enum NestedIf<'a> {
If(&'a ast::StmtIf),
Elif(&'a ElifElseClause),
}
impl<'a> NestedIf<'a> {
fn body(self) -> &'a [Stmt] {
match self {
NestedIf::If(stmt_if) => &stmt_if.body,
NestedIf::Elif(clause) => &clause.body,
}
}View on GitHub (pinned to 15f3fe6b15)
Solutions
- Manually combine the conditions: replace `if a: if b:` with `if a and b:` and dedent the body, then rerun ruff
- Read the wrapped `{err}` detail to find the libcst failure and adjust the source (e.g. move comments) so the fix applies
- Add `# noqa: SIM102` if the nesting is intentional (e.g. readability or short-circuit side effects)
Example fix
// before
if a:
if b:
do()
// after
if a and b:
do() Defensive patterns
Strategy: try-catch
Validate before calling
# only simple two-level nesting is fixable
python - <<'EOF'
import ast, sys
tree = ast.parse(open(sys.argv[1]).read())
for n in ast.walk(tree):
if isinstance(n, ast.If) and len(n.body) == 1 and isinstance(n.body[0], ast.If) and not n.orelse and not n.body[0].orelse:
print('SIM102 candidate at line', n.lineno)
EOF Try / catch
ruff check --select SIM102 --fix . 2>&1 | tee fix.log; grep -q 'Failed to collapse' fix.log && echo 'collapse failed: merge conditions manually'
Prevention
- Prefer flat boolean conditions (`if a and b:`) over nested guards while writing code
- Avoid comments and stray statements between the two `if` headers
- Run the formatter/linter early so nesting never accumulates in generated code
When it happens
Trigger: `ruff check --fix` on a nested `if` (including `elif` forms) whose libcst round-trip fails — e.g. the outer body contains comments or structure the collapse transformer rejects.
Common situations: Nested ifs with `elif` chains, comments between the two `if` headers, or unusual indentation that the libcst collapse can't normalize.
Related errors
- Expected indented block to have at least one statement
- Expected one inner if statement
- Failed to collapse `with`: {err}
- Unable to fix multiline statement
- Expected indented block to have at least one statement
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-09-05).
Data as JSON: /api/errors/7e4f382ccea8fc1d.
Report an issue: GitHub.