gitbutlerapp/gitbutler · error
Configured target branch has no branch name
Error message
Configured target branch has no branch name
What it means
The target (base) branch metadata from the workspace configuration must include a branch name, since landing merges into it and computes ref names from it. `branch_land` bails when `base_branch.short_name` is empty, meaning the configured target branch entry is malformed.
Solutions
- Re-configure the target branch in GitButler (set push/fetch target via the app or `but` target setup) so a branch name is stored
- Inspect the workspace metadata (virtual_branches.toml / target config) and fix the empty branch name
- As a workaround, delete the stale target entry and re-add it pointing at the correct remote branch
Example fix
// before (corrupted metadata)
{"target": {"branch": "", "remote": "origin"}}
// after
{"target": {"branch": "main", "remote": "origin"}} Defensive patterns
Strategy: validation
Validate before calling
// read workspace target metadata before calling
let short_name = base_branch.short_name.clone();
if short_name.is_empty() {
println!("target branch misconfigured; re-set the push target");
return Ok(());
} Try / catch
match land_result {
Err(e) if e.to_string().contains("has no branch name") => {
reconfigure_target_branch();
retry_land();
}
other => other?,
} Prevention
- Avoid hand-editing GitButler metadata files; use the app/CLI to set the target
- After setup, print or assert the configured target branch name
- Back up virtual_branches.toml before manual migrations
When it happens
Trigger: Calling `but merge` when the workspace's base-branch data has an empty `short_name` — a corrupted or incompletely written `virtual_branches.toml` target entry, or an empty parsed branch name.
Common situations: Hand-edited or corrupted GitButler config file; an interrupted setup that wrote the target without a branch name; old config format migrated poorly.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- `but merge` requires an active GitButler workspace…
- Configured target branch has no push remote
- a committed transaction always materializes a workspace
- `but land` requires an active GitButler workspace…
- `but merge` requires an active GitButler workspace…
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/5f08965c2316e8e8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-api/src/land/mod.rs:197
) -> anyhow::Result<BranchLandResult> {
let base_branch = {
let mut guard = ctx.exclusive_worktree_access();
{
let (_repo, ws, _db) = ctx.workspace_and_db_with_perm(guard.read_permission())?;
if !ws.kind.has_managed_ref() {
bail!(
"`but merge` requires an active GitButler workspace (`gitbutler/workspace`). \
Switch into the workspace and try again."
);
}
}
crate::legacy::virtual_branches::get_base_branch_data(ctx, guard.write_permission())?
.ok_or_else(|| anyhow::anyhow!("No base branch configured"))?
};
let target_branch_name = base_branch.short_name.clone();
if target_branch_name.is_empty() {
bail!("Configured target branch has no branch name");
}
let fetch_remote_name = base_branch.remote_name.clone();
let push_remote_name = if base_branch.push_remote_name.is_empty() {
fetch_remote_name.clone()
} else {
base_branch.push_remote_name.clone()
};
if push_remote_name.is_empty() {
bail!("Configured target branch has no push remote");
}
// Triangular remotes (fetch remote != push remote) are out of scope for now: the post-land
// reconcile reads the fetch remote's tracking ref, so a push to a different remote would not
// advance it and the reconcile would silently no-op. Refuse before mutating anything.
if push_remote_name != fetch_remote_name {
bail!(
"`but merge` does not yet support triangular remotes (fetch `{fetch_remote_name}`, \
push `{push_remote_name}`). Merge via a pull request instead, or configure a single \View on GitHub (pinned to 58e5313667)