gitbutlerapp/gitbutler · error
Stack has no ID
Error message
Stack has no ID
What it means
After finding the stack containing the target branch, the absorb plan reads stack.id to filter hunk assignments by stack. If the stack entry carries no ID, planning aborts with 'Stack has no ID'. This is an internal invariant violation: current stacks are expected to always have IDs, so a None here means legacy or damaged workspace metadata.
Source
Thrown at crates/but-api/src/legacy/absorb.rs:154
perm.read_permission(),
)?;
let all_assignments = worktree_changes.assignments;
let dependencies = worktree_changes.dependencies;
// Get the stack ID for this branch
let stacks = crate::legacy::workspace::stacks(ctx, None)?;
// Find the stack that contains this branch
let stack = stacks
.iter()
.find(|s| {
s.heads
.iter()
.any(|h| h.name.to_str().map(|n| n == branch_name).unwrap_or(false))
})
.ok_or_else(|| anyhow::anyhow!("Branch not found: {branch_name}"))?;
let stack_id = stack.id.ok_or_else(|| anyhow::anyhow!("Stack has no ID"))?;
// Filter assignments to just this stack
let candidates: Vec<AbsorbCandidate> = all_assignments
.into_iter()
.filter(|a| a.stack_id == Some(stack_id))
.map(Into::into)
.collect();
if candidates.is_empty() {
anyhow::bail!("No uncommitted changes assigned to branch: {branch_name}");
}
(candidates, dependencies)
}
AbsorptionTarget::TreeChanges {
changes,
assigned_stack_id,
} => {View on GitHub (pinned to 2497b8007a)
Solutions
- Recreate the stack (new stack, then move/recreate the branch in it) so it gets a fresh ID, and retry absorb.
- Update GitButler so pending workspace metadata migrations run for the project.
- If reproducible on a current version, report it — stacks without IDs should not be reachable.
Defensive patterns
Strategy: try-catch
Validate before calling
fn stack_has_id(stack: &Stack) -> bool {
stack.id.is_some()
} Type guard
fn usable_for_absorb(stack: &Stack) -> bool {
stack.id.is_some() && !stack.heads.is_empty()
} Try / catch
match absorption_plan_with_perm(ctx, target, perm) {
Err(err) if err.to_string().contains("Stack has no ID") => {
rebuild_stack_metadata(ctx)?; // recreate the stack with a fresh ID; do not retry unchanged
}
other => other?,
} Prevention
- Run pending app migrations before agent/absorb flows.
- Fail fast on stacks lacking IDs when listing workspaces.
- Back up workspace metadata across upgrades.
When it happens
Trigger: absorption_plan_with_perm(Branch) on workspace data where the matching stack's id field is None — older metadata formats, partially migrated projects, or corrupted stack entries from interrupted operations.
Common situations: Projects carried across major GitButler version upgrades without running migrations; manually edited metadata; restored databases.
Related errors
- No stacks found in the workspace
- Branch not found: {branch_name}
- Unable to determine target commit for unassigned change: {}
- No uncommitted changes assigned to branch: {branch_name}
- Stack has no branches
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/487a19aafadb882c.
Report an issue: GitHub.