gitbutlerapp/gitbutler · error

Target ref '{name}' resolved from '{target_ref}' is not a re

Error message

Target ref '{name}' resolved from '{target_ref}' is not a remote-tracking branch; use --extra-target for arbitrary revisions

What it means

Thrown by args_to_tips() in but-debug's revision command when --target-ref resolves to a reference whose gix category is not RemoteBranch. The revision graph treats 'target' tips specially (the remote-tracking branch the workspace integrates with), so arbitrary revisions must go through --extra-target instead.

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; use --extra-target for arbitrary revisions"
            );
            let id = reference.peel_to_id()?.detach();
            Ok(Tip::integrated(id, Some(name)))
        })
        .transpose()?
    {
        tips.push(tip);
    }

    if let Some(tip) = graph_args
        .extra_target
        .as_deref()
        .map(|rev| {
            repo.rev_parse_single(rev)
                .map(|id| Tip::integrated(id.detach(), None))
                .with_context(|| format!("Failed to resolve extra target '{rev}'"))

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Use the remote-tracking name, e.g. --target-ref origin/main or the full refs/remotes/origin/main.
  2. If you really want an arbitrary revision (local branch, tag, commit), pass it via --extra-target instead of --target-ref.
  3. Run `git for-each-ref refs/remotes` to see which remote-tracking refs actually exist in this clone.

Example fix

# before
but debug revision graph --target-ref main

# after
but debug revision graph --target-ref refs/remotes/origin/main
# or, for an arbitrary revision:
but debug revision graph --extra-target main
Defensive patterns

Strategy: validation

Validate before calling

# before invoking the CLI
if ! git show-ref --verify --quiet "refs/remotes/$TARGET"; then
  echo "$TARGET is not a remote-tracking branch" >&2
  exit 2
fi

Try / catch

Wrap the CLI invocation and on non-zero exit, if stderr contains 'not a remote-tracking branch', print a hint to use refs/remotes/<remote>/<branch> or --extra-target.

Prevention

When it happens

Trigger: Running `but debug revision ... --target-ref <name>` where <name> is a local branch (refs/heads/...), a tag (refs/tags/...), HEAD, or any non refs/remotes/... reference.

Common situations: Passing 'main' instead of 'origin/main' or 'refs/remotes/origin/main'; passing a tag or a commit SHA where the graph expects the integrated remote-tracking branch; a ref name that git resolves through a symbolic ref to something non-remote.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/50d8f6d15224204c. Report an issue: GitHub.