{"record":{"id":"caf363e38b6ba729","repo":"gitbutlerapp/gitbutler","slug":"commit-was-marked-as-not-conflictable-but-resu","errorCode":null,"errorMessage":"Commit {} was marked as not conflictable, but resulted in a conflicted state","messagePattern":"Commit (.+?) was marked as not conflictable, but resulted in a conflicted state","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-rebase/src/graph_rebase/rebase.rs","lineNumber":74,"sourceCode":"                                    _ => bail!(\"A parent in the output graph is not a pick\"),\n                                }\n                            })\n                            .collect::<Result<Vec<_>>>()?,\n                    };\n\n                    let outcome = cherry_pick(\n                        &self.repo,\n                        pick.id,\n                        &ontos,\n                        pick.pick_mode,\n                        pick.tree_merge_mode,\n                        pick.sign_commit,\n                    )?;\n\n                    if matches!(outcome, CherryPickOutcome::ConflictedCommit(_))\n                        && !pick.conflictable\n                    {\n                        bail!(\n                            \"Commit {} was marked as not conflictable, but resulted in a conflicted state\",\n                            pick.id\n                        );\n                    }\n\n                    match outcome {\n                        CherryPickOutcome::Commit(new_id)\n                        | CherryPickOutcome::ConflictedCommit(new_id)\n                        | CherryPickOutcome::Identity(new_id) => {\n                            let mut new_pick = pick.clone();\n                            new_pick.id = new_id;\n                            let new_idx = output_graph.add_node(Step::Pick(new_pick));\n                            graph_mapping.insert(step_idx, new_idx);\n                            if !pick.exclude_from_tracking {\n                                history.update_mapping(pick.id, new_id);\n                            }\n\n                            new_idx","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-rebase/src/graph_rebase/rebase.rs#L56-L92","documentation":"Each pick in a graph rebase plan carries a `conflictable` flag declaring whether a conflicted outcome is acceptable for that commit. When the cherry pick of a commit marked not-conflictable nevertheless produces a conflicted commit, the rebase bails: the plan's assumptions no longer match the history being rebased (typically a plan built over a stale graph).","triggerScenarios":"Executing a plan where `conflictable=false` for a commit whose pick returns `CherryPickOutcome::ConflictedCommit` — history or refs changed between plan creation and execution.","commonSituations":"Plans computed from cached graphs; refs updated by another window or a background fetch between planning and execution; concurrent worktrees sharing objects.","solutions":["Rebuild the graph and plan from the current state, then execute the fresh plan","Mark such picks conflictable if conflicts are genuinely tolerable for this flow","Serialize planning and execution so no ref updates land in between"],"exampleFix":"// before: execute a plan captured earlier\neditor.rebase(&stale_plan)?; // may hit the not-conflictable invariant\n\n// after: rebuild the plan right before execution\nlet graph = but_graph::Graph::from_repo(&repo)?;\nlet plan = build_plan(&graph);\neditor.rebase(&plan)?;","handlingStrategy":"retry","validationCode":"// Rust: build the plan immediately before executing it, from a fresh graph\nlet graph = but_graph::Graph::from_repo(&repo)?;\nlet plan = build_plan(&graph); // conflictable flags reflect current state\neditor.rebase(&plan)?;","typeGuard":null,"tryCatchPattern":"On this invariant bail, discard the plan, rebuild graph + plan from current state, and retry once; if it reproduces, report a bug including the commit id from the message.","preventionTips":["Never cache plans across ref updates; plan and execute in one locked window","Hold the workspace/repository lock from planning through execution to bar concurrent ref changes"],"tags":["rebase","plan-mismatch","conflict","invariant","graph-rebase"],"backgroundTag":"stale-plan-execution","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}