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
- Add or restore a remote named 'origin': git remote add origin <url> && git fetch origin (gix resolves 'origin' as the default).
- If origin is absent, keep exactly one remote so remote_default_name is unambiguous.
- Skip guessing entirely: set the target branch explicitly in GitButler project metadata / the app so target_ref.is_some() short-circuits this path.
- 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
- Keep a single canonical push remote, or name it 'origin'.
- Persist target_ref in project metadata at onboarding so the guess path never runs.
- Validate remote topology before enabling project actions.
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
- No HEAD reference found for remote {remote_name}
- Remote HEAD for {remote_name} is not symbolic
- Target branch {target_ref_name} not found
- No base branch configured
- RepoOwnership
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/c758de0ecfcb2838.
Report an issue: GitHub.