{"record":{"id":"e8b141dd3ef2f8be","repo":"astral-sh/ruff","slug":"else-clause","errorCode":null,"errorMessage":"else clause","messagePattern":"else clause","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rules/pylint/rules/useless_else_on_loop.rs","lineNumber":75,"sourceCode":"    #[derive_message_formats]\n    fn message(&self) -> String {\n        \"`else` clause on loop without a `break` statement; \\\n            remove the `else` and dedent its contents\"\n            .to_string()\n    }\n\n    fn fix_title(&self) -> Option<String> {\n        Some(\"Remove `else`\".to_string())\n    }\n}\n\n/// PLW0120\npub(crate) fn useless_else_on_loop(checker: &Checker, stmt: &Stmt, body: &[Stmt], orelse: &[Stmt]) {\n    if orelse.is_empty() || loop_exits_early(body) {\n        return;\n    }\n\n    let else_range = identifier::else_(stmt, checker.locator().contents()).expect(\"else clause\");\n\n    let mut diagnostic = checker.report_diagnostic(UselessElseOnLoop, else_range);\n    diagnostic.try_set_fix(|| {\n        remove_else(\n            stmt,\n            orelse,\n            else_range,\n            checker.locator(),\n            checker.indexer(),\n            checker.stylist(),\n        )\n    });\n}\n\n/// Returns `true` if the given body contains a `break` statement.\nfn loop_exits_early(body: &[Stmt]) -> bool {\n    body.iter().any(|stmt| match stmt {\n        Stmt::If(ast::StmtIf {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_linter/src/rules/pylint/rules/useless_else_on_loop.rs#L57-L93","documentation":"An .expect in the PLW0120 useless-else-on-loop rule: the code tries to locate the `else` keyword of a loop statement that the earlier guard confirmed has a non-empty orelse block. Firing it means the AST/range lookup for the else identifier failed despite the block existing — an internal invariant break, not a user error.","triggerScenarios":"Thrown at crates/ruff_linter/src/rules/pylint/rules/useless_else_on_loop.rs:75 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use the orelse block's range directly instead of re-locating the else keyword","Skip the diagnostic when the else identifier cannot be located"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}