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

  1. Run `but setup` (or app onboarding) to re-select the default target branch, which rewrites default.target in virtual_branches.toml.
  2. Inspect .git/gitbutler/virtual_branches.toml and verify the [default] section contains a target ref entry.
  3. 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

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


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