gitbutlerapp/gitbutler · error · anyhow::Error
Stack has no branches
Error message
Stack has no branches
What it means
During `but teardown` without an explicit --checkout-to, but takes the first branch of the first stack as the branch to check out after tearing the workspace down. If that stack exists but its branches list is empty, there is no checkout target and teardown aborts.
Source
Thrown at crates/but/src/command/legacy/teardown.rs:141
let stacks = match crate::legacy::workspace::applied_stacks(ctx) {
Ok(stacks) => stacks,
Err(_e) => {
try_stack_fixes(ctx, out)?;
crate::legacy::workspace::applied_stacks(ctx)
.context("Failed to retrieve stacks after attempting fixes")?
}
};
let target_branch_name = if let Some(checkout_to) = checkout_to {
checkout_to
} else {
if let Some(target_stack) = stacks.first() {
target_stack
.branches
.first()
.map(|branch| branch.name.clone())
.ok_or_else(|| anyhow::anyhow!("Stack has no branches"))?
} else {
return Err(bad_input(
"Failed to determine checkout target branch. Specify a target branch with `--checkout-to <branch>`.",
).into());
}
};
if let Some(out) = out.for_human() {
writeln!(
out,
" {}",
t.success
.paint(format!("✓ Will check out: {target_branch_name}"))
)?;
writeln!(out)?;
}
// Uninstall managed hooks before checking outView on GitHub (pinned to caf1f223d3)
Solutions
- Pass the target explicitly: `but teardown --checkout-to <branch>`
- Open the project in the GitButler app (or inspect `but status`) and fix or delete the empty stack, then rerun teardown
- In scripts, always pass --checkout-to so teardown does not depend on stack contents
Example fix
# before but teardown # first stack has no branches -> error # after but teardown --checkout-to main
Defensive patterns
Strategy: validation
Validate before calling
let stacks = list_stacks(&mut ctx)?; let has_target = stacks.first().is_some_and(|s| s.branches.first().is_some()); anyhow::ensure!(has_target, "no branch to check out; pass --checkout-to");
Try / catch
On this error, retry the command with `--checkout-to <known-branch>`; that path bypasses the stack lookup entirely.
Prevention
- Always pass --checkout-to in scripted teardowns
- Delete empty stacks in the workspace before tearing down
When it happens
Trigger: `but teardown` (no --checkout-to) where stacks[0].branches is empty: the stack's branches were all deleted or merged in the GitButler app, or an earlier partial teardown left an empty stack.
Common situations: Workspaces where every branch of the first stack was already integrated; workspace state left inconsistent by an interrupted teardown.
Related errors
- GitButler mode exit required: please run `but teardown` to p
- Could not find stack containing commit {commit_ref}
- When using OpenRouter, you must provide a valid API key
- HTTP Error ${response.statusText}: ${text}
- No stack selected!
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/107d84b608ef23c0.
Report an issue: GitHub.