gastownhall/beads · error

delete %s: %w

Error message

delete %s: %w

What it means

During deleteProtoSubgraph, each issue in the loaded subgraph is deleted inside a transaction, children first (reverse order). This wrapper attaches the failing issue ID to the underlying tx.DeleteIssue error, so you know exactly which node of the subgraph could not be removed. On failure the whole delete transaction rolls back, leaving the subgraph intact.

Source

Thrown at cmd/bd/cook.go:1054

	for _, child := range step.Children {
		collectDependencies(child, idMapping, deps)
	}
}

// deleteProtoSubgraph deletes a proto and all its children.
func deleteProtoSubgraph(ctx context.Context, s storage.DoltStorage, protoID string) error {
	// Load the subgraph
	subgraph, err := loadTemplateSubgraph(ctx, s, protoID)
	if err != nil {
		return fmt.Errorf("load proto: %w", err)
	}

	// Delete in reverse order (children first)
	return transact(ctx, s, fmt.Sprintf("bd: delete proto subgraph %s", protoID), func(tx storage.Transaction) error {
		for i := len(subgraph.Issues) - 1; i >= 0; i-- {
			issue := subgraph.Issues[i]
			if err := tx.DeleteIssue(ctx, issue.ID); err != nil {
				return fmt.Errorf("delete %s: %w", issue.ID, err)
			}
		}
		return nil
	})
}

// printFormulaSteps prints steps in a tree format.
func printFormulaSteps(steps []*formula.Step, indent string) {
	for i, step := range steps {
		connector := "├──"
		if i == len(steps)-1 {
			connector = "└──"
		}

		// Collect dependency info
		var depParts []string
		if len(step.DependsOn) > 0 {
			depParts = append(depParts, fmt.Sprintf("depends: %s", strings.Join(step.DependsOn, ", ")))

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped issue ID and check what references it (`bd show <issueID>`, dependency edges) — remove or detach blockers first if storage refuses
  2. Retry the operation; the transaction is atomic so a transient driver error leaves data intact
  3. Check database connectivity/health (`bd doctor`) if the cause is a driver error
  4. If deletion keeps failing on constraint edges, file an issue — cascade behavior belongs behind the storage interface
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check for edges that may block deletion
for _, issue := range subgraph.Issues {
    if deps, _ := s.GetDependencies(ctx, issue.ID); len(deps) > 0 {
        // confirm storage cascade behavior before deleting
    }
}

Try / catch

if err := deleteProtoSubgraph(ctx, s, protoID); err != nil {
    var targetErr error
    if errors.As(err, &targetErr) {
        // message contains "delete <issueID>:" — extract and inspect that issue
    }
    return fmt.Errorf("subgraph delete rolled back atomically: %w", err)
}

Prevention

When it happens

Trigger: tx.DeleteIssue(ctx, issue.ID) fails for one issue in the subgraph while executing the `bd: delete proto subgraph <id>` transaction — e.g. referential constraints (dependencies/labels referencing the issue), driver error, or the issue vanishing mid-transaction.

Common situations: Deleting a proto whose children still have dependency edges the storage layer refuses to cascade; concurrent modification of a child issue; Dolt constraint or connectivity errors during bulk delete.

Related errors


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