{"record":{"id":"78ac437eb11830a0","repo":"gitbutlerapp/gitbutler","slug":"failed-to-find-branch-target-branch-refname","errorCode":null,"errorMessage":"failed to find branch {target_branch_refname}","messagePattern":"failed to find branch (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gitbutler-git/src/context.rs","lineNumber":106,"sourceCode":"            force_push_protection,\n            refspec,\n            askpass_broker,\n            push_opts,\n        )\n    }\n\n    fn git_test_push(\n        &self,\n        remote_name: &str,\n        branch_name: &str,\n        askpass: Option<Option<StackId>>,\n    ) -> Result<()> {\n        let target_branch_refname: gix::refs::FullName =\n            format!(\"refs/remotes/{remote_name}/{branch_name}\").try_into()?;\n        let repo = self.repo.get()?;\n        let mut branch = repo\n            .try_find_reference(&target_branch_refname.to_string())?\n            .ok_or(anyhow!(\"failed to find branch {target_branch_refname}\"))?;\n\n        let commit_id = branch.peel_to_commit()?.id;\n        let branch_name = format!(\"test-push-{}\", now_ms());\n        let refname: gix::refs::FullName =\n            format!(\"refs/remotes/{remote_name}/{branch_name}\").try_into()?;\n\n        self.push(\n            commit_id,\n            refname.clone(),\n            false,\n            false,\n            None,\n            askpass,\n            vec![],\n        )\n        .map_err(|err| anyhow!(err.to_string()))?;\n\n        let empty_refspec = Some(format!(\":refs/heads/{branch_name}\"));","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/gitbutler-git/src/context.rs#L88-L124","documentation":"Thrown by GitContextExt::git_test_push (crates/gitbutler-git/src/context.rs). The helper builds refs/remotes/{remote_name}/{branch_name} and calls repo.try_find_reference() on it; if that ref does not exist locally it bails with this message. The ref is used as the source commit for a throwaway test-push branch, so a missing remote-tracking ref aborts the whole connectivity/permission test.","triggerScenarios":"Calling git_test_push(remote_name, branch_name) before ever fetching that remote; passing a branch name that only exists on another remote or was deleted upstream; passing a wrong remote name (typo, or remote only configured in another clone); shallow/partial clones that never wrote refs/remotes/<remote>/<branch>.","commonSituations":"Auth-flow test immediately after adding a project before the first fetch completed; the target branch was renamed or deleted on the server; users with multiple remotes (origin + fork) picking the wrong one; CI environments where the clone was created with --single-branch so other remote-tracking refs are absent.","solutions":["Fetch the remote first so refs/remotes/{remote}/{branch} exists: ctx.fetch(remote_name, None) before git_test_push","Verify the ref locally: `git branch -r --list '{remote}/{branch}'` (or repo.try_find_reference) and fix the remote/branch arguments if missing","If the branch was deleted upstream, test against a branch that exists, e.g. the repository default branch","For --single-branch clones, re-clone or configure the refspec to fetch the needed branch"],"exampleFix":"// before\nctx.git_test_push(&remote_name, &branch_name, askpass)?;\n\n// after: make sure the remote-tracking ref exists before testing\nctx.fetch(&remote_name, None)?;\nlet refname = format!(\"refs/remotes/{remote_name}/{branch_name}\");\nif ctx.repo.get()?.try_find_reference(&refname)?.is_none() {\n    anyhow::bail!(\"{refname} not found after fetch — check remote/branch names\");\n}\nctx.git_test_push(&remote_name, &branch_name, askpass)?;","handlingStrategy":"validation","validationCode":"ctx.fetch(&remote_name, None)?; // materialize refs/remotes/<remote>/<branch>\nlet refname = format!(\"refs/remotes/{remote_name}/{branch_name}\");\nlet repo = ctx.repo.get()?;\nif repo.try_find_reference(&refname)?.is_none() {\n    // pick a branch that exists, e.g. the default branch, instead of failing later\n    anyhow::bail!(\"{refname} missing — branch not fetched or wrong remote\");\n}","typeGuard":null,"tryCatchPattern":"match ctx.git_test_push(&remote_name, &branch_name, askpass) {\n    Ok(()) => Ok(()),\n    Err(err) if err.to_string().contains(\"failed to find branch\") => {\n        // remote-tracking ref absent: fetch once and retry with the default branch\n        ctx.fetch(&remote_name, None)?;\n        ctx.git_test_push(&remote_name, default_branch, askpass)\n    }\n    Err(err) => Err(err),\n}","preventionTips":["Always fetch a remote before running connectivity/push tests against its branches","Derive branch names from the project's target branch or `git branch -r` output rather than hardcoded values","In single-branch clones, extend the refspec so the tested branch is fetched"],"tags":["git","fetch","remote-tracking","push","gitbutler"],"backgroundTag":"missing-remote-tracking-branch","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}