gitbutlerapp/gitbutler · error

No push remote set or more than one remote

Error message

No push remote set or more than one remote

What it means

When a project has no target branch configured (ctx.project_meta().target_ref is None), GitButler tries to guess one like `git symbolic-ref refs/remotes/origin/HEAD` using gix's remote_default_name(Push). That returns None when the repository has no push remote at all or several remotes with no unambiguous default (none named 'origin'), so default target setup in default_target_setting_if_none fails with this error.

Source

Thrown at crates/but-action/src/lib.rs:149

                .project_meta()?
                .target_ref_or_err()?
                .to_string()
                .parse()?;
            gitbutler_branch_actions::set_base_branch(ctx, &target_ref, perm).map(|_| ())
        }
    }
}

fn default_target_setting_if_none(ctx: &Context) -> anyhow::Result<()> {
    if ctx.project_meta()?.target_ref.is_some() {
        return Ok(());
    }
    // Lets do the equivalent of `git symbolic-ref refs/remotes/origin/HEAD --short` to guess the default target.

    let repo = ctx.repo.get()?;
    let remote_name = repo
        .remote_default_name(gix::remote::Direction::Push)
        .ok_or_else(|| anyhow::anyhow!("No push remote set or more than one remote"))?
        .to_string();

    let mut head_ref = repo
        .find_reference(&format!("refs/remotes/{remote_name}/HEAD"))
        .map_err(|_| anyhow::anyhow!("No HEAD reference found for remote {remote_name}"))?;
    let target_ref_name = head_ref
        .target()
        .try_name()
        .ok_or_else(|| anyhow::anyhow!("Remote HEAD for {remote_name} is not symbolic"))?
        .to_owned();

    let head_commit = head_ref.peel_to_commit()?;

    ctx.set_project_meta(ProjectMeta {
        target_ref: Some(target_ref_name),
        target_commit_id: Some(head_commit.id),
        push_remote: None,
    })?;

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Add or restore a remote named 'origin': git remote add origin <url> && git fetch origin (gix resolves 'origin' as the default).
  2. If origin is absent, keep exactly one remote so remote_default_name is unambiguous.
  3. Skip guessing entirely: set the target branch explicitly in GitButler project metadata / the app so target_ref.is_some() short-circuits this path.
  4. For legitimate multi-remote setups, configure the workspace target once via the UI before running agent actions.

Example fix

git remote add origin git@github.com:org/repo.git
git fetch origin
git remote set-head origin --auto
# then retry the action, or set the target branch explicitly in the GitButler app
Defensive patterns

Strategy: validation

Validate before calling

fn default_push_remote_is_unambiguous(repo: &gix::Repository) -> bool {
    repo.remote_default_name(gix::remote::Direction::Push).is_some()
}

// run before any action that may guess the default target:
if ctx.project_meta()?.target_ref.is_none()
    && !default_push_remote_is_unambiguous(repo)
{
    anyhow::bail!("configure a target branch or add an 'origin' remote first");
}

Try / catch

match default_target_setting_if_none(ctx) {
    Err(err) if err.to_string().contains("No push remote") => {
        prompt_set_target_branch(); // writes ProjectMeta.target_ref so guessing is skipped
    }
    other => other?,
}

Prevention

When it happens

Trigger: Any path through default_target_setting_if_none (e.g. prepare_handle_changes) on a repo with zero remotes, or multiple remotes none of which is 'origin' — gix cannot pick a default push remote, so the ok_or_else triggers.

Common situations: Fresh `git init` repo never given a remote; repos where origin was renamed (upstream + fork setups); exotic CI checkouts with many remotes; projects onboarded before a remote was added.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/c758de0ecfcb2838. Report an issue: GitHub.