gitbutlerapp/gitbutler · error
Failed to cut remote name
Error message
Failed to cut remote name {longest_remote} off of shorthand name {shorthand_name} What it means
Thrown when parsing a remote-tracking ref name: after identifying the longest registered remote name, the code tries to strip `<remote>/` from the shorthand ref name. If the shorthand does not start with that remote name followed by `/`, no valid remote/branch split exists and this error is raised. It signals a ref name that claims a remote-tracking form but does not match any known remote prefix.
Solutions
- Check the ref name actually matches `refs/remotes/<remote>/<branch>` for a remote listed in `git remote -v`.
- Re-add or fix the missing remote in `.git/config` so the prefix matches.
- Delete stale refs (`git branch -r -d` or `git update-ref -d`) that no longer correspond to a configured remote.
- Ensure the ref name contains a `/` after the remote name.
Example fix
// before: ref = refs/remotes/oldremote/feature, remote 'oldremote' removed from config // after: git remote add oldremote <url> (or delete the stale ref) git update-ref -d refs/remotes/oldremote/feature
Defensive patterns
Strategy: validation
Validate before calling
fn is_remote_tracking(name: &str, remotes: &[String]) -> bool {
remotes.iter().any(|r| name.strip_prefix("refs/remotes/").and_then(|s| s.strip_prefix(r)).map_or(false, |s| s.starts_with('/')))
} Type guard
fn split_remote_tracking<'a>(name: &'a str, remotes: &[String]) -> Option<(&'a str, &'a str)> {
let short = name.strip_prefix("refs/remotes/")?;
remotes.iter().filter_map(|r| short.strip_prefix(r)?.strip_prefix('/').map(|b| (r.as_str(), b))).next()
} Prevention
- Keep .git/config remotes in sync with existing refs; run git fetch --prune regularly.
- Validate ref names against git remote before passing to reference parsing.
- Avoid manually crafting refs/remotes/... names.
When it happens
Trigger: Calling target_identity_from_ref_name with a ref whose name does not begin with one of the repo's registered remote names plus `/` (e.g. a ref under an unregistered remote, or a malformed ref like `refs/remotes/originbranch` with no slash).
Common situations: Repos where `.git/config` remote entries were removed or renamed while remote-tracking refs remain; refs created by tools using non-standard naming; a remote name with unusual characters causing the longest-match to mismatch.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- failed to determine remote and branch name for
- Couldn't find remote refspecs that would match
- failed to determine remote for non remote-tracking branch
- Failed to find remote branch's corresponding remote
- Failed to find remote branch's corresponding remote
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/f7876003851e0c8e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/gitbutler-branch/src/reference_ext.rs:39
fn identity(&self, remotes: &gix::remote::Names) -> Result<BranchIdentity> {
let (category, shorthand_name) = self
.category_and_short_name()
.context("Branch could not be categorized")?;
if !matches!(category, Category::RemoteBranch) {
return Ok(shorthand_name.try_into()?);
}
let longest_remote = remotes
.iter()
.rfind(|reference_name| shorthand_name.starts_with(reference_name))
.ok_or(anyhow::anyhow!(
"Failed to find remote branch's corresponding remote"
))?;
let shorthand_name: &BStr = shorthand_name
.strip_prefix(longest_remote.as_bytes())
.and_then(|str| str.strip_prefix(b"/"))
.ok_or(anyhow::anyhow!(
"Failed to cut remote name {longest_remote} off of shorthand name {shorthand_name}"
))?
.into();
Ok(shorthand_name.try_into()?)
}
}
View on GitHub (pinned to 58e5313667)