gitbutlerapp/gitbutler · error
failed to find branch {target_branch_refname}
Error message
failed to find branch {target_branch_refname} What it means
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.
Source
Thrown at crates/gitbutler-git/src/context.rs:106
force_push_protection,
refspec,
askpass_broker,
push_opts,
)
}
fn git_test_push(
&self,
remote_name: &str,
branch_name: &str,
askpass: Option<Option<StackId>>,
) -> Result<()> {
let target_branch_refname: gix::refs::FullName =
format!("refs/remotes/{remote_name}/{branch_name}").try_into()?;
let repo = self.repo.get()?;
let mut branch = repo
.try_find_reference(&target_branch_refname.to_string())?
.ok_or(anyhow!("failed to find branch {target_branch_refname}"))?;
let commit_id = branch.peel_to_commit()?.id;
let branch_name = format!("test-push-{}", now_ms());
let refname: gix::refs::FullName =
format!("refs/remotes/{remote_name}/{branch_name}").try_into()?;
self.push(
commit_id,
refname.clone(),
false,
false,
None,
askpass,
vec![],
)
.map_err(|err| anyhow!(err.to_string()))?;
let empty_refspec = Some(format!(":refs/heads/{branch_name}"));View on GitHub (pinned to caf1f223d3)
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
Example fix
// before
ctx.git_test_push(&remote_name, &branch_name, askpass)?;
// after: make sure the remote-tracking ref exists before testing
ctx.fetch(&remote_name, None)?;
let refname = format!("refs/remotes/{remote_name}/{branch_name}");
if ctx.repo.get()?.try_find_reference(&refname)?.is_none() {
anyhow::bail!("{refname} not found after fetch — check remote/branch names");
}
ctx.git_test_push(&remote_name, &branch_name, askpass)?; Defensive patterns
Strategy: validation
Validate before calling
ctx.fetch(&remote_name, None)?; // materialize refs/remotes/<remote>/<branch>
let refname = format!("refs/remotes/{remote_name}/{branch_name}");
let repo = ctx.repo.get()?;
if repo.try_find_reference(&refname)?.is_none() {
// pick a branch that exists, e.g. the default branch, instead of failing later
anyhow::bail!("{refname} missing — branch not fetched or wrong remote");
} Try / catch
match ctx.git_test_push(&remote_name, &branch_name, askpass) {
Ok(()) => Ok(()),
Err(err) if err.to_string().contains("failed to find branch") => {
// remote-tracking ref absent: fetch once and retry with the default branch
ctx.fetch(&remote_name, None)?;
ctx.git_test_push(&remote_name, default_branch, askpass)
}
Err(err) => Err(err),
} Prevention
- 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
When it happens
Trigger: 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>.
Common situations: 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.
Related errors
- Failed to find remote branch's corresponding remote
- Unknown
- GitForcePushProtection
- failed to determine remote and branch name for `{branch}`
- Failed to communicate with LM Studio server: ${error instanc
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/78ac437eb11830a0.
Report an issue: GitHub.