{"record":{"id":"9b33a90e3c9c65f3","repo":"astral-sh/ruff","slug":"unable-to-fix-multiline-statement-9b33a9","errorCode":null,"errorMessage":"Unable to fix multiline statement","messagePattern":"Unable to fix multiline statement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs","lineNumber":23,"sourceCode":"use ruff_python_ast::whitespace;\nuse ruff_python_codegen::Stylist;\nuse ruff_source_file::LineRanges;\nuse ruff_text_size::Ranged;\n\nuse crate::Edit;\nuse crate::Locator;\nuse crate::cst::matchers::{match_function_def, match_indented_block, match_statement, match_with};\nuse crate::fix::codemods::CodegenStylist;\n\n/// (SIM117) Convert `with a: with b:` to `with a, b:`.\npub(crate) fn fix_multiple_with_statements(\n    locator: &Locator,\n    stylist: &Stylist,\n    with_stmt: &ast::StmtWith,\n) -> Result<Edit> {\n    // Infer the indentation of the outer block.\n    let Some(outer_indent) = whitespace::indentation(locator.contents(), with_stmt) else {\n        bail!(\"Unable to fix multiline statement\");\n    };\n\n    // Extract the module text.\n    let contents = locator.lines_str(with_stmt.range());\n\n    // If the block is indented, \"embed\" it in a function definition, to preserve\n    // indentation while retaining valid source code. (We'll strip the prefix later\n    // on.)\n    let module_text = if outer_indent.is_empty() {\n        contents.to_string()\n    } else {\n        format!(\"def f():{}{contents}\", stylist.line_ending().as_str())\n    };\n\n    // Parse the CST.\n    let mut tree = match_statement(&module_text)?;\n\n    let statement = if outer_indent.is_empty() {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_linter/src/rules/flake8_simplify/rules/fix_with.rs#L5-L41","documentation":"`fix_multiple_with_statements` (the SIM117 collapse of consecutive `with` statements) begins by inferring the indentation of the `with` statement via `whitespace::indentation`; if none can be inferred it aborts with this message rather than emit a wrongly indented merged `with`. Like the other flake8-simplify bails, the diagnostic still fires and only the autofix is skipped.","triggerScenarios":"`ruff check --fix` on consecutive `with` statements (SIM117) whose indentation cannot be derived — e.g. module-level multiline `with` headers, tabs/space mixtures, or statements whose range spans odd line layouts.","commonSituations":"Multiline parenthesized `with` headers, files reformatted with different indent styles, generated code blocks lacking normal block indentation.","solutions":["Normalize indentation in the file (consistent spaces) and rerun `ruff check --fix`","Merge the consecutive `with` statements manually into `with A as a, B as b:`","Suppress with `# noqa: SIM117` when separate `with` blocks are deliberate"],"exampleFix":"// before\nwith open(a) as f:\n    with open(b) as g:\n        data = f.read() + g.read()\n// after\nwith open(a) as f, open(b) as g:\n    data = f.read() + g.read()","handlingStrategy":"validation","validationCode":"# ensure indentation is inferable (spaces only, standard 4-space blocks) before SIM117 fix\npython - <<'EOF'\nimport sys\nsrc = open(sys.argv[1]).read()\nassert '\\t' not in src, 'normalize tabs to spaces first'\nEOF","typeGuard":null,"tryCatchPattern":"ruff check --select SIM117 --fix . || python - <<'EOF'\nprint('SIM117 fix skipped: collapse the with statements manually')\nEOF","preventionTips":["Write `with A as a, B as b:` directly instead of stacking `with` blocks","Run ruff format before ruff check --fix so indentation heuristics succeed","Keep parenthesized multiline `with` headers in a consistent style"],"tags":["ruff","flake8-simplify","sim117","autofix"],"backgroundTag":"linter-autofix-skipped","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}