gastownhall/beads · error
re-add %s.%s: %w
Error message
re-add %s.%s: %w
What it means
After removing orphaned rows, relinkSeveredCloneLocalFKs re-adds each missing foreign key with ALTER TABLE ... ADD CONSTRAINT. If the ALTER fails, this error wraps it, meaning the FK remains severed and future writes may not enforce referential integrity for clone-local references.
Source
Thrown at cmd/bd/doctor/fix/clone_local_fks.go:170
fk.Table, fk.Column, fk.RefTable, fk.RefColumn, fk.Table, fk.Column,
)
result, err := db.Exec(deleteOrphans)
if err != nil {
return fmt.Errorf("delete %s orphans: %w", fk.Table, err)
}
if verbose {
removed, _ := result.RowsAffected()
fmt.Printf(" Removed %d orphaned row(s) from %s\n", removed, fk.Table)
}
}
//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec, not user input.
addConstraint := fmt.Sprintf(
`ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) ON DELETE CASCADE ON UPDATE CASCADE`,
fk.Table, fk.Constraint, fk.Column, fk.RefTable, fk.RefColumn,
)
if _, err := db.Exec(addConstraint); err != nil {
return fmt.Errorf("re-add %s.%s: %w", fk.Table, fk.Constraint, err)
}
fmt.Printf(" ✓ Re-linked %s.%s (%d orphaned row(s) removed)\n", fk.Table, fk.Constraint, fk.Orphans)
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the scan + fix (`bd doctor`) so orphans created in between are deleted before the constraint is re-added.
- Check the wrapped error for 'duplicate constraint' — if so, the constraint already exists and the scan is stale; rescan.
- Ensure the database user has ALTER privileges on the issues tables.
- Verify the actual schema matches the CloneLocalFKs spec (table/column names) after any migration.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm no orphans remain and the constraint name is free: var orphans int db.QueryRow(`SELECT COUNT(*) FROM issues t WHERE t.<fk> IS NOT NULL AND NOT EXISTS (...)`).Scan(&orphans) var cons int db.QueryRow(`SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME = ?`, fk.Constraint).Scan(&cons) // orphans == 0 && cons == 0 means ALTER should succeed
Try / catch
if err := CloneLocalFKEnforcement(ctx, db, verbose); err != nil && strings.Contains(err.Error(), "re-add") {
// ALTER failed: rescan (frees races/stale state), then retry once
return err
} Prevention
- Always run scan+delete+re-add as one doctor fix cycle, not manually
- Ensure the DB user has ALTER privileges
- Keep schema in sync with the CloneLocalFKs spec after migrations
- Re-run doctor if the fix is interrupted mid-cycle
When it happens
Trigger: ALTER TABLE ADD CONSTRAINT fails in relinkSeveredCloneLocalFKs (cmd/bd/doctor/fix/clone_local_fks.go:170) — remaining orphan rows the delete step missed, duplicate constraint name, ALTER privileges denied, or Dolt engine rejecting the FK definition.
Common situations: Races where new orphans were inserted between delete and re-add, running with a DB user lacking ALTER privileges, schema drift after manual migrations renaming tables/columns away from the CloneLocalFKs spec.
Related errors
- check %s exists: %w
- check %s.%s: %w
- count %s orphans: %w
- delete %s orphans: %w
- failed to load config: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6846779f9013c34f.
Report an issue: GitHub.