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

  1. Check the ref name actually matches `refs/remotes/<remote>/<branch>` for a remote listed in `git remote -v`.
  2. Re-add or fix the missing remote in `.git/config` so the prefix matches.
  3. Delete stale refs (`git branch -r -d` or `git update-ref -d`) that no longer correspond to a configured remote.
  4. 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

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


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)