gastownhall/beads · warning

proto %s already exists (use --force to replace)

Error message

proto %s already exists (use --force to replace)

What it means

In persist mode, `bd cook` writes a proto bead with the given ID. If a proto with that ID already exists in the store and `--force` was not passed, cook aborts to protect the existing proto subgraph from being silently replaced. The message tells you to re-run with `--force` to delete and recreate it.

Source

Thrown at cmd/bd/cook.go:317

		}
		if len(missingVars) > 0 {
			return fmt.Errorf("runtime mode requires all variables to have values\nMissing: %s\nProvide with: --var %s=<value>",
				strings.Join(missingVars, ", "), missingVars[0])
		}

		// Substitute variables in the formula
		substituteFormulaVars(resolved, inputVars)
	}
	return outputJSON(resolved)
}

// persistCookFormula creates a proto bead in the database (persist mode)
func persistCookFormula(ctx context.Context, resolved *formula.Formula, protoID string, force bool, vars, bondPoints []string) error {
	// Check if proto already exists
	existingProto, err := store.GetIssue(ctx, protoID)
	if err == nil && existingProto != nil {
		if !force {
			return fmt.Errorf("proto %s already exists (use --force to replace)", protoID)
		}
		// Delete existing proto and its children
		if err := deleteProtoSubgraph(ctx, store, protoID); err != nil {
			return fmt.Errorf("deleting existing proto: %w", err)
		}
	}

	// Create the proto bead from the formula
	result, err := cookFormula(ctx, store, resolved, protoID)
	if err != nil {
		return fmt.Errorf("cooking formula: %w", err)
	}

	if jsonOutput {
		return outputJSON(cookResult{
			ProtoID:    result.ProtoID,
			Formula:    resolved.Formula,
			Created:    result.Created,

View on GitHub (pinned to 71377f2769)

Solutions

  1. If replacement is intended, re-run with `--force`: `bd cook <formula> --mode=persist --force` (this deletes the existing proto and its children first)
  2. Choose a different proto ID if both protos should coexist
  3. Inspect the existing proto first (`bd show <protoID>`) to decide whether to replace or keep it
  4. Clean stale protos from prior runs before re-running persistent cook scripts

Example fix

// before
bd cook deploy --mode=persist --proto bd-proto-1
// after
bd cook deploy --mode=persist --proto bd-proto-1 --force
Defensive patterns

Strategy: validation

Validate before calling

if _, err := store.GetIssue(ctx, protoID); err == nil {
    // proto exists: require --force or pick another ID before cooking
    return fmt.Errorf("proto %s exists; pass --force to replace", protoID)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "already exists") {
    // decide: rerun with --force or choose a new proto ID
    return err
}

Prevention

When it happens

Trigger: Running `bd cook <formula> --mode=persist` with a proto ID that already exists in the database and without `--force`; re-running a cook command after a previous successful persist; two runs targeting the same proto ID.

Common situations: Replaying a cook script (CI or local) without cleaning state; an earlier interrupted run left the proto in place; reusing an ID that another formula or teammate already cooked.

Related errors


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