gastownhall/beads · error
re-key id %s -> %s: %w
Error message
re-key id %s -> %s: %w
What it means
The per-row failure of the re-key loop: an UPDATE <table> SET id = ? WHERE id = ? failed while rewriting one dependency edge from its old (random UUID) id to the deterministic depid value. The message names both ids so the exact offending row is identifiable. Any row already at its deterministic id is skipped, so this only fires on genuinely divergent rows.
Source
Thrown at internal/storage/schema/dep_id_backfill.go:90
if !target.Valid {
// Malformed row with no target (ck_dep_one_target should prevent this);
// leave it untouched for `bd doctor` to surface rather than guessing.
continue
}
if want := depid.New(issueID, target.String); want != id {
todo = append(todo, rekey{oldID: id, newID: want})
}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return false, err
}
for _, r := range todo {
//nolint:gosec // G201: table is a hardcoded constant, never user input.
if _, err := db.ExecContext(ctx, fmt.Sprintf(`UPDATE %s SET id = ? WHERE id = ?`, table),
r.newID, r.oldID); err != nil {
return true, fmt.Errorf("re-key id %s -> %s: %w", r.oldID, r.newID, err)
}
}
return len(todo) > 0, nil
}
// columnExists reports whether table.column is present in the current schema.
func columnExists(ctx context.Context, db DBConn, table, column string) (bool, error) {
var count int
if err := db.QueryRowContext(ctx,
`SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?`,
table, column).Scan(&count); err != nil {
return false, err
}
return count > 0, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Deduplicate edges first: find rows sharing (issue_id, target) and delete extras so only one row can claim each deterministic id
- Check for foreign keys or unique keys referencing the old id and resolve/update them before re-keying
- Retry the migration — already-updated rows are skipped, so it resumes at the failed row
- Inspect the row by id (`SELECT * FROM dependencies WHERE id = '<oldID>'`) to confirm its shape before manual fixes
Example fix
-- before: duplicate edges with different random ids collide
DELETE d1 FROM dependencies d1 JOIN dependencies d2
ON d1.issue_id = d2.issue_id
AND COALESCE(d1.depends_on_issue_id, d1.depends_on_wisp_id, d1.depends_on_external) =
COALESCE(d2.depends_on_issue_id, d2.depends_on_wisp_id, d2.depends_on_external)
AND d1.id > d2.id;
-- after: re-run migration; remaining row re-keys cleanly Defensive patterns
Strategy: validation
Validate before calling
-- before rekey, ensure no row already occupies the target deterministic id SELECT COUNT(*) FROM dependencies WHERE id = '<expected deterministic id>';
Try / catch
if _, err := db.Exec("UPDATE dependencies SET id = ? WHERE id = ?", newID, oldID); err != nil {
if dberrors.IsUniqueViolation(err) {
// delete/merge the duplicate edge holding newID, then retry
}
return err
} Prevention
- Deduplicate dependency edges sharing (issue_id, target) before migration
- Avoid concurrent writers during migration passes
- The message names old→new ids — look the row up directly to diagnose
When it happens
Trigger: The UPDATE statement for a specific (oldID → newID) pair errors: most commonly a unique-key collision (another row already holds newID — duplicate edges), a foreign-key reference still pointing at oldID, connection loss, or lock contention with a concurrent writer.
Common situations: Two identical dependency edges exist with different random UUIDs — the first UPDATE wins, the second collides on the deterministic id; a foreign key on dependencies.id blocks the rename; Dolt server under concurrent migration from a peer.
Related errors
- dependencies: %w
- wisp_dependencies: %w
- dolt directory is required
- dolt binary not found
- dolt path is not executable
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0415f64cca2996bf.
Report an issue: GitHub.