gitbutlerapp/gitbutler · error

No stacks found in the workspace

Error message

No stacks found in the workspace

What it means

In the simplified handle-changes commit flow, stacks_creating_if_none is supposed to return the applied stacks, creating one when the workspace has none. If it still yields an empty list, the subsequent stacks.first() fails with this error — a defensive invariant violation meaning the workspace reported no usable stacks even after the create-if-none step.

Source

Thrown at crates/but-action/src/simple.rs:70

        context_lines,
    )
    .map_err(|err| serde_error::Error::new(&*err))?;
    if assignments.is_empty() {
        return Ok(Outcome {
            updated_branches: vec![],
        });
    }

    // Get the current stacks in the workspace, creating one if none exists.
    let stacks = stacks_creating_if_none(repo, ws, meta, perm)?;

    // Put the assignments into buckets by stack ID.
    let mut stack_assignments: HashMap<StackId, Vec<DiffSpec>> =
        stacks.iter().map(|s| (s.id, vec![])).collect();
    let default_stack_id = stacks
        .first()
        .map(|s| s.id)
        .ok_or_else(|| anyhow::anyhow!("No stacks found in the workspace"))?;
    for assignment in assignments {
        if let Some(stack_id) = assignment.stack_id {
            stack_assignments
                .entry(stack_id)
                .or_default()
                .push(assignment.into());
        } else if exclusive_stack.is_none() {
            // If there is an exclusive stack. We don't want to do anything with
            // the unassigned changes.
            stack_assignments
                .entry(default_stack_id)
                .or_default()
                .push(assignment.into());
        }
    }
    // Go over the stack_assignments and flatten the diff specs for each stack.
    for (_, specs) in stack_assignments.iter_mut() {
        *specs = but_workspace::flatten_diff_specs(specs.clone());

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Create or apply a stack in the GitButler app (so at least one applied branch exists), then retry handle-changes.
  2. Check workspace health first: `but status` should list at least one applied branch.
  3. If it persists, workspace state is likely inconsistent — re-onboard the project or restore from the oplog.
  4. Report as a bug: this branch is defensive and should be unreachable when stack creation works.
Defensive patterns

Strategy: validation

Validate before calling

// before invoking handle-changes:
let stacks = workspace::stacks(ctx, None)?;
let has_applied = stacks.iter().any(|s| !s.heads.is_empty());
anyhow::ensure!(has_applied, "apply or create a stack before running handle-changes");

Prevention

When it happens

Trigger: but-action simple::handle_changes with non-empty hunk assignments but an empty stacks list — stacks that exist but are all filtered out (unapplied / without refs) and the create-if-none step not producing an applied stack.

Common situations: Inconsistent or half-migrated workspace metadata; stacks left in detached/archived state after failed operations; races where another process mutated workspace refs between listing and commit.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/97a0398d508ee826. Report an issue: GitHub.