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
- If replacement is intended, re-run with `--force`: `bd cook <formula> --mode=persist --force` (this deletes the existing proto and its children first)
- Choose a different proto ID if both protos should coexist
- Inspect the existing proto first (`bd show <protoID>`) to decide whether to replace or keep it
- 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
- Derive proto IDs uniquely per run (timestamp/prefix) in automated scripts
- Check bd show <protoID> before persistent cook runs
- Clean stale protos at the start of CI jobs that persist formulas
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
- cooking formula: %w
- deleting existing proto: %w
- ErrAlreadyClaimed
- ErrAssigneeMismatch
- parsing formula: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f2038ff6101b246a.
Report an issue: GitHub.