gastownhall/beads · error
adding %s for the 0058 repair: %w
Error message
adding %s for the 0058 repair: %w
What it means
Wraps a failure while adding one of the final key/index definitions (wispDepFinalKeys) to wisp_dependencies during the 0058 repair. Each key is added only if absent, so this fires when the ALTER TABLE ... ADD INDEX/KEY statement itself fails.
Source
Thrown at internal/storage/schema/wisp_dep_forward_repair.go:464
}
return nil
}
// ensureWispDepFinalKeysAndConstraints completes the final shape. Each object
// is added only if absent, so this finishes a partially-rebuilt table rather
// than failing on a duplicate key name -- and re-running it on a converged
// database does nothing at all.
func ensureWispDepFinalKeysAndConstraints(ctx context.Context, db DBConn) error {
for _, k := range wispDepFinalKeys {
present, err := schemaIndexExists(ctx, db, wispDepTable, k.name)
if err != nil {
return err
}
if present {
continue
}
if _, err := db.ExecContext(ctx, "ALTER TABLE wisp_dependencies "+k.definition); err != nil {
return fmt.Errorf("adding %s for the 0058 repair: %w", k.name, err)
}
}
for _, c := range wispDepFinalConstraints {
present, err := schemaConstraintExists(ctx, db, wispDepTable, c.name)
if err != nil {
return err
}
if present {
continue
}
if _, err := db.ExecContext(ctx,
"ALTER TABLE wisp_dependencies ADD CONSTRAINT "+c.name+" "+c.definition); err != nil {
return fmt.Errorf("adding %s for the 0058 repair: %w", c.name, err)
}
}
return nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Run dedupeWispDepNaturalIdentity / the full repair first so duplicate rows are removed before UNIQUE keys are added
- Check the wrapped error for 'Duplicate entry' and delete the offending duplicate rows manually, then re-run
- Run the repair with a DB account that has ALTER/INDEX privileges
- Retry when no other connections hold locks on wisp_dependencies
Example fix
-- before: UNIQUE key add fails ALTER TABLE wisp_dependencies ADD UNIQUE KEY uk_wisp_dep_natural (...); -- Duplicate entry -- after delete duplicate rows first (or re-run the repair's dedupe step), then re-run the repair
Defensive patterns
Strategy: retry
Validate before calling
// pre-check duplicates that would break UNIQUE keys SELECT issue_id, depends_on_issue_id, depends_on_wisp_id, depends_on_external, COUNT(*) c FROM wisp_dependencies GROUP BY 1,2,3,4 HAVING c > 1;
Try / catch
if err := ensureWispDepFinalKeysAndConstraints(ctx, db); err != nil {
if strings.Contains(err.Error(), "Duplicate entry") {
// re-run dedupe step, then retry once
}
return err
} Prevention
- Run the dedupe step before adding UNIQUE keys
- Check for 'Duplicate entry' in the wrapped error and clean rows before retrying
- Avoid concurrent sessions during DDL repairs
- Grant ALTER/INDEX privileges to the migration user
When it happens
Trigger: During repairWispDependenciesForwardShape, ensureWispDepFinalKeysAndConstraints executes 'ALTER TABLE wisp_dependencies <key.definition>' for an absent key and the DDL fails — e.g. duplicate values still present that violate a UNIQUE key, insufficient privileges, or a Dolt/MySQL DDL limitation.
Common situations: Repairing a legacy store where dedupe was skipped or failed silently, leaving duplicate natural-identity rows so UNIQUE key creation fails; running under a restricted DB account; concurrent access holding metadata locks on the table.
Related errors
- pre-repair for migration %s: %w
- dropping idx_wisp_dep_type_target for the 0058 repair: %w
- dropping %s for the 0058 repair: %w
- dropping the wisp_dependencies primary key for the 0058 repa
- dropping wisp_dependencies.depends_on_id for the 0058 repair
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e45f1da940513673.
Report an issue: GitHub.