gastownhall/beads · error

failed to add label %s to %s: %w

Error message

failed to add label %s to %s: %w

What it means

Wraps a failure from tx.AddLabel while attaching labels to freshly cooked issues inside the cook --persist transaction. If any label cannot be added, the error names both the label and the target issue ID, and the transaction rolls back, undoing the issue creation as well.

Source

Thrown at cmd/bd/cook.go:919

	// This prevents orphaned issues if label/dependency creation fails.
	err := transact(ctx, s, fmt.Sprintf("bd: cook formula %s", protoID), func(tx storage.Transaction) error {
		// Flatten unregistered step types to task (with a warning) before
		// inserting, mirroring cloneSubgraphInto (pour). Without this,
		// PrepareIssueForInsert rejects them with "invalid issue type" and
		// the whole cook --persist transaction rolls back.
		if err := flattenUnregisteredIssueTypes(ctx, storeMolWriter{DoltStorage: s, tx: tx}, issues, deps); err != nil {
			return fmt.Errorf("checking custom types: %w", err)
		}

		// Create all issues
		if err := tx.CreateIssues(ctx, issues, actor); err != nil {
			return fmt.Errorf("failed to create issues: %w", err)
		}

		// Add labels
		for _, l := range labels {
			if err := tx.AddLabel(ctx, l.issueID, l.label, actor); err != nil {
				return fmt.Errorf("failed to add label %s to %s: %w", l.label, l.issueID, err)
			}
		}

		// Add dependencies
		for _, dep := range deps {
			if err := tx.AddDependency(ctx, dep, actor); err != nil {
				return fmt.Errorf("failed to create dependency: %w", err)
			}
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &cookFormulaResult{

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read label and issue ID from the message; check the label string for invalid characters or length and fix it in the formula's labels block
  2. Verify the label is not rejected as a duplicate if the store enforces uniqueness
  3. Check database health if the failure is storage-level (`bd doctor`)
  4. Retry after transient errors — the transaction rollback leaves no partial labels

Example fix

# before (formula labels block)
labels: ["very long label with  spaces & symbols!"]
# after
labels: ["review-needed"]
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate label strings before the transaction
for _, l := range labels {
    if strings.TrimSpace(l.label) == "" || len(l.label) > 64 {
        return fmt.Errorf("invalid label %q for %s", l.label, l.issueID)
    }
}

Try / catch

if err := tx.AddLabel(ctx, l.issueID, l.label, actor); err != nil {
    return fmt.Errorf("failed to add label %s to %s: %w", l.label, l.issueID, err)
}
// at call site:
if strings.Contains(err.Error(), "failed to add label") {
    // message names the label and issue; sanitize label in the formula and re-run
}

Prevention

When it happens

Trigger: tx.AddLabel returns an error for a generated issue: target issue ID not found in the transaction (unlikely since just created), label violates validation/format rules, duplicate label rejected, or storage-level failure.

Common situations: Label strings generated from formula metadata contain invalid characters or exceed length limits; database/storage error mid-transaction; concurrent modification of the issue outside the transaction.

Related errors


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