gastownhall/beads · error

squashing molecule: %w

Error message

squashing molecule: %w

What it means

Wrapped error from squashMoleculeInto during `bd mol squash`. The molecule and its wisp children loaded fine, but the actual squash — closing/collapsing the wisp children into the molecule root per --keep/--summary options — failed, rolling back the transaction.

Source

Thrown at cmd/bd/mol_proxied_server.go:496

	result, err := uow.RunTxResult(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (*SquashResult, string, error) {
		w := newUOWMolWriter(uw)

		moleculeID, err := utils.ResolvePartialID(ctx, w, in.moleculeArg)
		if err != nil {
			return nil, "", fmt.Errorf("resolving molecule ID %s: %w", in.moleculeArg, err)
		}
		subgraph, err := loadTemplateSubgraph(ctx, w, moleculeID)
		if err != nil {
			return nil, "", fmt.Errorf("loading molecule: %w", err)
		}
		wispChildren := wispChildrenOf(subgraph)
		if len(wispChildren) == 0 {
			return &SquashResult{MoleculeID: moleculeID, SquashedCount: 0}, "", nil
		}

		result, err := squashMoleculeInto(ctx, w, subgraph.Root, wispChildren, in.keepChildren, in.summary, actor)
		if err != nil {
			return nil, "", fmt.Errorf("squashing molecule: %w", err)
		}
		return result, fmt.Sprintf("bd: mol squash %s", moleculeID), nil
	})
	if err != nil {
		return HandleErrorRespectJSON("%v", err)
	}

	if result.SquashedCount == 0 && result.DigestID == "" {
		if jsonOutput {
			return outputJSON(result)
		}
		fmt.Printf("No ephemeral children found for molecule %s\n", result.MoleculeID)
		return nil
	}

	return renderSquashResult(result)
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped inner error to find the specific child or write that failed
  2. Run `bd show <molID>` and inspect child states; close/reopen inconsistent children manually if needed
  3. Retry — the transaction rolls back atomically so state remains consistent
  4. Check that the command is not running under a conflicting readonly/ephemeral mode (CheckReadonly analog)
Defensive patterns

Strategy: try-catch

Validate before calling

// Inspect child states first
bd mol show <molID>   // confirm wisps are open and squashable

Type guard

func squashFailed(err error) bool {
    return err != nil && strings.Contains(err.Error(), "squashing molecule")
}

Try / catch

err := runMolSquashProxiedServer(ctx, molID)
if squashFailed(err) {
    // transaction rolled back; molecule unchanged — safe to inspect and retry
    log.Printf("squash aborted, state consistent: %v", err)
}

Prevention

When it happens

Trigger: Run `bd mol squash <molID>` where squashMoleculeInto fails: updating/closing wisp children hits a storage error, a status transition is invalid, the actor cannot close an issue (validation), or summary text handling fails.

Common situations: Wisp children already closed or in a state the squash logic rejects; concurrent modification of children during squash; storage write failure; readonly mode or permission constraint.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/f95f82422ae96754. Report an issue: GitHub.