astral-sh/ruff · info

Failed to collapse `with`: {err}

Error message

Failed to collapse `with`: {err}

What it means

In rule SIM117 (multiple `with` statements should be collapsed into one), the fix pipelines the statements through a libcst-based collapse helper; when that helper returns an `Err`, the diagnostic check wraps it in this bail message that includes the underlying error. The lint finding still fires, but no autofix is produced.

Source

Thrown at crates/ruff_linter/src/rules/flake8_simplify/rules/ast_with.rs:206

                    checker.stylist(),
                    with_stmt,
                ) {
                    Ok(edit) => {
                        if edit.content().is_none_or(|content| {
                            fits(
                                content,
                                with_stmt.into(),
                                checker.locator(),
                                checker.settings().pycodestyle.max_line_length,
                                checker.settings().tab_size,
                            )
                        }) {
                            Ok(Some(Fix::safe_edit(edit)))
                        } else {
                            Ok(None)
                        }
                    }
                    Err(err) => bail!("Failed to collapse `with`: {err}"),
                }
            });
        }
    }
}

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Manually merge the consecutive `with` statements into a single `with A as a, B as b:` block and rerun ruff
  2. Inspect the inner `{err}` message in the output to see which libcst step failed and fix the syntax it objects to (comments, blank lines, indentation)
  3. Skip the fix with `# noqa: SIM117` if keeping separate `with` blocks is intentional

Example fix

// before
with open(a) as f:
    with open(b) as g:
        ...
// after
with open(a) as f, open(b) as g:
    ...
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-check: consecutive with statements without interleaving comments are usually fixable
python - <<'EOF'
import ast, sys
tree = ast.parse(open(sys.argv[1]).read())
for n in ast.walk(tree):
    if isinstance(n, ast.With):
        if isinstance(getattr(n, 'body', [None])[0], ast.With):
            print('SIM117 candidate at line', n.lineno)
EOF

Try / catch

# apply the autofix, and on failure do it by hand:
ruff check --select SIM117 --fix path/ || echo 'manual collapse required; see ruff output for inner error'

Prevention

When it happens

Trigger: `ruff check --fix` on nested/sequential `with` statements whose collapse fails internally — for example `with open(a) as f, open(b) as g:` bodies the libcst transformer cannot re-indent, or a `with` at module level where indentation cannot be inferred.

Common situations: Multiline `with` statements with comments or parenthesized context managers, files with mixed indentation (tabs/spaces), and generated code where the statement range doesn't round-trip through libcst.

Related errors


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