gitbutlerapp/gitbutler · error
No default target branch set.
Error message
No default target branch set.
What it means
check_project_setup (crates/but/src/command/legacy/setup.rs:516) bails when the loaded workspace graph has no default target branch (ws.graph.project_meta.target_ref is None). The target ref is persisted in .git/gitbutler/virtual_branches.toml; without it GitButler cannot compute the workspace base. The code's TODO marks no-target as expected to become acceptable, but today it is a hard setup failure.
Source
Thrown at crates/but/src/command/legacy/setup.rs:516
let head_name = head
.referent_name()
.map(|n| n.shorten().to_owned())
.unwrap_or_default();
if !head_name.starts_with(b"gitbutler/") {
anyhow::bail!("Not currently on a gitbutler/* branch.");
}
// When on gitbutler/edit, the project was already set up when entering edit mode.
// The workspace graph built from gitbutler/edit doesn't expose the target ref or
// remote configuration, but both are still configured in virtual_branches.toml
// and will be accessible when returning to gitbutler/workspace.
if head_name == b"gitbutler/edit" {
return Ok(true);
}
// TODO(legacy): it's fine to have no target.
if ws.graph.project_meta.target_ref.is_none() {
anyhow::bail!("No default target branch set.");
}
// check if there is a remote
if ws.remote_name().is_none()
&& repo
.remote_default_name(gix::remote::Direction::Push)
.is_none()
{
anyhow::bail!(
"Neither found push remote found in workspace nor unambiguously in the Git repository configuration."
)
};
Ok(true)
}
/// Creates a 'gb-local' remote pointing to this repository and creates tracking refs for the default branch.
fn setup_local_remote(repo: &gix::Repository, out: &mut OutputChannel) -> anyhow::Result<String> {View on GitHub (pinned to caf1f223d3)
Solutions
- Run `but setup` (or app onboarding) to re-select the default target branch, which rewrites default.target in virtual_branches.toml.
- Inspect .git/gitbutler/virtual_branches.toml and verify the [default] section contains a target ref entry.
- If the file is corrupted, remove it and re-run setup to regenerate it; branches already pushed remain recoverable from remote refs.
Example fix
# .git/gitbutler/virtual_branches.toml before [default] remote = "origin" # after [default] remote = "origin" target = "refs/heads/main"
Defensive patterns
Strategy: validation
Validate before calling
let (repo, ws, _) = ctx.workspace_and_db_with_perm(perm)?;
if ws.graph.project_meta.target_ref.is_none() {
// run setup / rewrite virtual_branches.toml [default] target before continuing
} Try / catch
if let Err(err) = check_project_setup(&ctx, &perm) {
if err.to_string().contains("No default target branch") {
// re-run `but setup` to repopulate the target, then retry once
}
} Prevention
- Keep .git/gitbutler/virtual_branches.toml under review when hand-editing gitbutler state.
- Complete onboarding (setup) fully; do not interrupt first-run initialization.
- After moving or cloning repos, re-run setup if GitButler commands fail.
When it happens
Trigger: Running setup-checked commands when virtual_branches.toml is missing, empty, or lacks the default target entry: interrupted first-run setup, hand-edited or corrupted config, or config loss after repo moves.
Common situations: Setup was aborted between creating the workspace branch and writing the target; virtual_branches.toml deleted or truncated; repo copied without .git/gitbutler; downgrade/upgrade wrote a config the current reader cannot map to target_ref.
Related errors
- Cannot import TOML into DB: TOML does not exist or is invali
- configured storage path '{}' resolves to '.git' itself; choo
- configured storage path '{}' resolves inside '.git' but not
- Not currently on a gitbutler/* branch.
- cannot snapshot a null target commit id
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/296e4f736086631e.
Report an issue: GitHub.