gitbutlerapp/gitbutler · error
Target ref ' ' resolved from ' ' is not a remote-tracking…
Error message
Target ref '{name}' resolved from '{target_ref}' is not a remote-tracking branch What it means
Thrown by `args_to_tips` in but-debug's revision command handling when the `--target` ref string resolves (via `find_reference`) to a reference whose fully-qualified name is not in the `Category::RemoteBranch` category (e.g. `refs/heads/...` or `refs/tags/...`). The command only accepts remote-tracking branches such as `refs/remotes/origin/main` as integration targets, so any other ref kind is rejected with this message.
Solutions
- Use the remote-tracking form of the ref, e.g. `origin/main` instead of `main`.
- Fetch first (`git fetch origin`) so the remote-tracking branch exists, then retry.
- Verify the resolved ref category with `git rev-parse --symbolic-full-name <ref>`; it must start with refs/remotes/.
- If the target should legitimately be a local ref, the calling command/flag needs extending rather than the input changing.
Example fix
// before but-debug revision log --target main // after but-debug revision log --target origin/main
Defensive patterns
Strategy: validation
Validate before calling
async function ensureRemoteTrackingBranch(ref) {
const full = await git.revParse(['--symbolic-full-name', ref]);
if (!full.startsWith('refs/remotes/')) {
throw new Error(`${ref} resolves to ${full}; pass a remote-tracking branch like origin/main`);
}
return full;
} Prevention
- Always pass remote-tracking refs (origin/...) to revision commands targeting integration points.
- Fetch before invoking so remote-tracking branches are up to date.
- Check symbolic full names of refs in scripts before passing them as targets.
When it happens
Trigger: Running a but-debug revision subcommand (log or merge_base path) with a target-ref argument that names a local branch, tag, HEAD, or other non-remote-tracking ref, e.g. `--target main` resolving to `refs/heads/main`.
Common situations: Passing a local branch name instead of its remote-tracking counterpart; using a tag as the merge target; a repo where the branch has no remote counterpart; typos or shorthand refs that gix resolves to a non-remote category.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Aborting due to empty branch name
- Bare repositories are not supported.
- Branch ' ' not found
- Branch ' ' not found when checking for conflicts
- Branch " " has no conflicted commits.
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/52c5fa93df134fa0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-debug/src/command/revision.rs:160
);
};
writeln!(out, "{merge_base}")?;
Ok(())
}
fn args_to_tips(repo: &gix::Repository, graph_args: &RevisionGraphArgs) -> Result<Vec<Tip>> {
let mut tips = Vec::new();
if let Some(tip) = graph_args
.target_ref
.as_deref()
.map(|target_ref| {
let mut reference = repo
.find_reference(target_ref)
.with_context(|| format!("Failed to find target ref '{target_ref}'"))?;
let name = reference.name().to_owned();
ensure!(
name.category() == Some(Category::RemoteBranch),
"Target ref '{name}' resolved from '{target_ref}' is not a remote-tracking branch"
);
let id = reference.peel_to_id()?.detach();
Ok(Tip::integrated(id, Some(name)))
})
.transpose()?
{
tips.push(tip);
}
Ok(tips)
}
fn graph_for_revisions(
repo: &gix::Repository,
meta: &EmptyRefMetadata,
commits: &[gix::ObjectId],View on GitHub (pinned to 58e5313667)