{"record":{"id":"f6e87bfcb77bf028","repo":"astral-sh/ruff","slug":"failed-to-fix-invalid-comparison-due-to-missing-op","errorCode":null,"errorMessage":"Failed to fix invalid comparison due to missing op","messagePattern":"Failed to fix invalid comparison due to missing op","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs","lineNumber":113,"sourceCode":"                    lazy_located.as_ref().and_then(|located| located.get(index))\n                {\n                    assert_eq!(located_op.op, *op);\n                    if let Ok(content) = match located_op.op {\n                        CmpOp::Is => Ok::<String, Error>(\"==\".to_string()),\n                        CmpOp::IsNot => Ok(\"!=\".to_string()),\n                        node => {\n                            bail!(\"Failed to fix invalid comparison: {node:?}\")\n                        }\n                    } {\n                        Ok(Some(Fix::safe_edit(Edit::range_replacement(\n                            content,\n                            located_op.range,\n                        ))))\n                    } else {\n                        Ok(None)\n                    }\n                } else {\n                    bail!(\"Failed to fix invalid comparison due to missing op\")\n                }\n            });\n        }\n    }\n}\n\n#[derive(Debug, PartialEq, Eq, Copy, Clone)]\nenum IsCmpOp {\n    Is,\n    IsNot,\n}\n\nimpl From<&CmpOp> for IsCmpOp {\n    fn from(cmp_op: &CmpOp) -> Self {\n        match cmp_op {\n            CmpOp::Is => IsCmpOp::Is,\n            CmpOp::IsNot => IsCmpOp::IsNot,\n            _ => panic!(\"Expected CmpOp::Is | CmpOp::IsNot\"),","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ruff_linter/src/rules/pyflakes/rules/invalid_literal_comparisons.rs#L95-L131","documentation":"Companion bail for F632's autofix: the rule must have previously located and stored the comparison operator to replace, but when building the fix no located operator was found. Without it there is no range to edit, so the fixer aborts.","triggerScenarios":"`invalid_literal_comparison` iterated a comparison chain where the diagnostic condition held, but the operator lookup (`located_op`) returned nothing — e.g. the chain shape changed between collection and fix building — so the `assert_eq!`-guarded branch is not entered.","commonSituations":"Complex multi-operator comparisons, stale caches, or modified Ruff builds; practically rare in stock Ruff.","solutions":["Update Ruff to the latest version","Fix the comparison manually (use `==`/`!=` for literal comparisons)","Add `# noqa: F632` if the check is intentional"],"exampleFix":"# before\nif sys.version_info[0] is 3:\n    pass\n# after\nif sys.version_info[0] == 3:\n    pass","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid complex multi-operator literal comparisons","Fix identity comparisons manually","Report reproducible bail cases upstream"],"tags":["ruff","autofix","pyflakes","f632"],"backgroundTag":"autofix-failed-to-apply","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"}