{"record":{"id":"0c0a83fe337261bb","repo":"astral-sh/ruff","slug":"unable-to-fix-multiline-statement","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/collapsible_if.rs","lineNumber":317,"sourceCode":"                libcst_native::LeftParen::default(),\n                libcst_native::RightParen::default(),\n            )\n        }\n        libcst_native::Expression::IfExp(_)\n        | libcst_native::Expression::Lambda(_)\n        | libcst_native::Expression::NamedExpr(_) => expr.with_parens(\n            libcst_native::LeftParen::default(),\n            libcst_native::RightParen::default(),\n        ),\n        _ => expr,\n    }\n}\n\n/// Convert `if a: if b:` to `if a and b:`.\nfn collapse_nested_if(locator: &Locator, stylist: &Stylist, nested_if: NestedIf) -> Result<Edit> {\n    // Infer the indentation of the outer block.\n    let Some(outer_indent) = whitespace::indentation(locator.contents(), &nested_if) else {\n        bail!(\"Unable to fix multiline statement\");\n    };\n\n    // Extract the module text.\n    let contents = locator.lines_str(nested_if.range());\n\n    // If this is an `elif`, we have to remove the `elif` keyword for now. (We'll\n    // restore the `el` later on.)\n    let module_text = if nested_if.is_elif() {\n        Cow::Owned(contents.replacen(\"elif\", \"if\", 1))\n    } else {\n        Cow::Borrowed(contents)\n    };\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        module_text","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ruff_linter/src/rules/flake8_simplify/rules/collapsible_if.rs#L299-L335","documentation":"`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`.","triggerScenarios":"`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.","commonSituations":"Files with tabs/spaces mixing, statements at module level without surrounding block indentation, or heavily formatted multiline `if` headers.","solutions":["Normalize the file's indentation (consistent 4-space indents) so the outer `if` has detectable indentation and rerun ruff","Collapse the conditions manually into `if a and b:`","Suppress with `# noqa: SIM102` if the nested form is intended"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# verify the file uses consistent 4-space indentation before running the fix\npython - <<'EOF'\nimport sys\nsrc = open(sys.argv[1]).read()\nassert '\\t' not in src, 'tabs found; normalize indentation first'\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure and run ruff format so indentation is uniform before lint fixes","Keep multiline `if` headers parenthesized and conventionally indented","Detect tab/space mixing in CI before applying autofixes"],"tags":["ruff","flake8-simplify","sim102","indentation"],"backgroundTag":"linter-autofix-skipped","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}