astral-sh/ruff · warning
Compound statement cannot be inlined
Error message
Compound statement cannot be inlined
What it means
This is an internal fix-generation failure in Ruff's flake8-return superfluous-else fix. When removing `else: return ...` after a `return` in every branch, the fixer must compute the indentation of the `else` body's first statement to dedent it to the loop/function level. Ruff's `indentation()` helper returns None when the first body statement is not on a line of its own or the indent cannot be detected, so the fix is abandoned with this message.
Source
Thrown at crates/ruff_linter/src/rules/flake8_return/rules/function.rs:841
)))
} else {
// the start of the line where the `else`` is
let else_line_start = locator.line_start(elif_else.start());
// making a tokenizer to find the Colon for the `else`, not always on the same line!
let mut else_line_tokenizer =
SimpleTokenizer::starts_at(elif_else.start(), locator.contents());
// find the Colon for the `else`
let Some(else_colon) =
else_line_tokenizer.find(|token| token.kind == SimpleTokenKind::Colon)
else {
return Err(anyhow::anyhow!("Cannot find `:` in `else` statement"));
};
// get the indentation of the `else`, since that is the indent level we want to end with
let Some(desired_indentation) = indentation(locator.contents(), elif_else) else {
return Err(anyhow::anyhow!("Compound statement cannot be inlined"));
};
// If the statement is on the same line as the `else`, just remove the `else: `.
// Ex) `else: return True` -> `return True`
if let Some(first) = elif_else.body.first() {
if indexer.preceded_by_multi_statement_line(first, locator.contents()) {
return Ok(Fix::safe_edit(Edit::deletion(
elif_else.start(),
first.start(),
)));
}
}
// we're deleting the `else`, and it's Colon, and the rest of the line(s) they're on,
// so here we get the last position of the line the Colon is on
let else_colon_end = locator.full_line_end(else_colon.end());
// if there is a comment on the same line as the Colon, let's keep itView on GitHub (pinned to 26f38c119c)
Solutions
- Reformat the `else` block so the first statement starts on its own line with normal indentation, then rerun the fix
- Rewrite the `else: return ...` branch manually into the flat early-return form
- Report the snippet upstream as a fixable-lint false negative if the formatting looks standard
Example fix
// before (fix fails)
if cond:
return a
else: return b
// after (manual early-return form)
if cond:
return a
return b Defensive patterns
Strategy: try-catch
Validate before calling
import re
def fixable_else(source: str) -> bool:
# else body must start on its own line with plain indentation
return re.search(r"^\s*else:\s*$", source, re.M) is not None Try / catch
match ruff.fix(path) {
Ok(fixes) => apply(fixes),
Err(e) if e.to_string().contains("Compound statement cannot be inlined") => {
// fall back to reporting the diagnostic without an autofix
}
Err(e) => return Err(e),
} Prevention
- Keep `else:` and its first statement on separate, consistently indented lines
- Avoid multiple statements on the `else:` line
- Normalize tabs/spaces before running `ruff --fix`
When it happens
Trigger: Running the SIM125/RET505-style fix (`superfluous_else_node` -> `remove_else`) on an `if`/`else` where the `else:` body starts with a compound statement or the else-body's first statement's indentation cannot be detected (e.g. multi-statement or otherwise non-standard line layout around `else:`).
Common situations: Autofixing Python files with unusual formatting (multiple statements on the `else` line, tabs mixed with spaces, generated/minified code); users running `ruff --fix` see 'fix failed' rather than a normal diagnostic.
Related errors
- `else` is expected to be on its own line
- indented block to start with indentation
- Compound statement cannot be inlined
- Failed to collapse `with`: {err}
- Unable to fix multiline statement
AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05).
Data as JSON: /api/errors/0298094e258dc998.
Report an issue: GitHub.