{"record":{"id":"a393eb7f0c1a285f","repo":"gitbutlerapp/gitbutler","slug":"couldn-t-find-target-branch-to-move-in-workspace-w","errorCode":null,"errorMessage":"Couldn't find target branch to move in workspace with reference name: {target_branch_name}","messagePattern":"Couldn't find target branch to move in workspace with reference name: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-workspace/src/branch/move_branch.rs","lineNumber":505,"sourceCode":"    ///\n    /// ### What the future holds\n    /// In the future, where we're not afraid of complex graphs, we've figured out UX and data wrangling,\n    /// the concept of a segment might not hold, and hence we'll have to figure out a better way of determining\n    /// what to cut (e.g. letting the clients decide what to cut).\n    fn retrieve_branches_and_containers(\n        workspace: &but_graph::Workspace,\n        subject_branch_name: &FullNameRef,\n        target_branch_name: &FullNameRef,\n    ) -> anyhow::Result<(WorkspaceSegmentContext, WorkspaceSegmentContext)> {\n        let Some(source) = workspace.find_segment_and_stack_by_refname(subject_branch_name) else {\n            bail!(\n                \"Couldn't find branch to move in workspace with reference name: {subject_branch_name}\"\n            );\n        };\n\n        let Some(destination) = workspace.find_segment_and_stack_by_refname(target_branch_name)\n        else {\n            bail!(\n                \"Couldn't find target branch to move in workspace with reference name: {target_branch_name}\"\n            );\n        };\n        Ok((own_context(source), own_context(destination)))\n    }\n\n    /// Reorder `subject` to sit directly on top of `target` in the tip-to-base ad-hoc `order`.\n    ///\n    /// Mirrors the [`Position::Above`](crate::branch::create_reference::Position) case of\n    /// `create_reference`'s `insert_into_branch_stack_order`: `subject` is removed and re-inserted\n    /// at `target`'s slot, pushing `target` (and everything below it) down.\n    ///\n    /// If `target` isn't tracked yet (stale or empty metadata) it is appended first, so that a move\n    /// where *both* branches are missing adds them both - `subject` on top of `target` - instead of\n    /// silently clobbering the rest of the ordering down to just `subject`.\n    fn reorder_branch_in_stack_order(\n        mut order: Vec<gix::refs::FullName>,\n        target_branch_name: &FullNameRef,","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-workspace/src/branch/move_branch.rs#L487-L523","documentation":"The destination counterpart of the subject lookup: find_segment_and_stack_by_refname found the branch to move but not the target ref name it should be moved onto. The move is refused before any mutation because there is no destination stack/segment to operate on.","triggerScenarios":"Calling move_branch where target_branch_name is not a segment ref in the workspace projection — unapplied target, deleted branch, or a short name instead of a full refs/heads/... name.","commonSituations":"Drop target deleted between UI render and the API call; target branch name taken from user input without validation; short-vs-full ref name mismatch.","solutions":["Pass fully-qualified ref names for the target as well (refs/heads/<branch>).","Validate the target is an applied branch in the current workspace before enabling the move action.","Refresh the workspace and retry if the target was removed by a concurrent client."],"exampleFix":"// before\nmove_branch(editor, subject, target)?; // target may be gone\n\n// after\nlet (src, dst) = (\n    ws.find_segment_and_stack_by_refname(subject),\n    ws.find_segment_and_stack_by_refname(target),\n);\nensure!(src.is_some() && dst.is_some(), \"both branches must be applied in the workspace\");\nmove_branch(editor, subject, target)?;","handlingStrategy":"validation","validationCode":"let ws = successful_rebase.overlayed_graph()?.into_workspace()?;\nif ws.find_segment_and_stack_by_refname(target_branch_name).is_none() {\n    // target no longer applied; refresh the list and let the user re-pick\n    return refresh_branch_list();\n}","typeGuard":"fn target_in_workspace(ws: &but_graph::Workspace, name: &FullNameRef) -> bool {\n    ws.find_segment_and_stack_by_refname(name).is_some()\n}","tryCatchPattern":"match move_branch(editor, &subject, &target) {\n    Err(err) if err.to_string().contains(\"Couldn't find target branch\") => {\n        ui::error(\"The drop target is no longer available\");\n        Ok(default_outcome())\n    }\n    other => other,\n}","preventionTips":["Validate both subject and target exist in the fresh workspace projection.","Re-resolve drop targets at call time, not from cached UI state.","Use full ref names end to end."],"tags":["gitbutler","move-branch","branch-not-found","target","rust"],"backgroundTag":"branch-not-in-workspace","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}