gastownhall/beads · error
rekey aux row ids: %w
Error message
rekey aux row ids: %w
What it means
This error wraps a failure in rekeyAuxRowIDsAllPasses, the multi-pass rewrite that converges randomized primary keys on events/comments/snapshots tables (bd-6dnrw.2 and bd-ri8bd). Like the dependency rekey, it fires mid-pass after main migrations applied, so the returned applied count reflects work already done and the database may be mid-rewrite.
Source
Thrown at internal/storage/schema/schema.go:689
if err != nil {
return applied, fmt.Errorf("rekey dependency ids: %w", err)
}
backfilled = backfilled || rekeyed
// bd-6dnrw.2: converge the events/comments/snapshots primary keys that
// migration 0037 randomized per-clone, the same hazard class on the aux
// tables. Gated on the clone-local ignored marker (recorded later in this
// pass by ignoredSource.migrate) so it runs exactly once per clone instead
// of churning synced rows on every later migration pass — and on the
// pre-pass main cursor, so fresh clones of converged lineages record the
// marker without re-running the rewrite (bd-578h9.4).
// ...and the bd-ri8bd sibling: one more pass over the same tables for the
// rows minted with random UUIDv7 ids between the initial backfill and the
// switch to content-derived ids at insert time. Same machinery, own
// marker/sentinel/shipped-version gates, one shared cursor read.
auxRekeyed, err := rekeyAuxRowIDsAllPasses(ctx, db, mainVersionBefore)
if err != nil {
return applied, fmt.Errorf("rekey aux row ids: %w", err)
}
backfilled = backfilled || auxRekeyed
touchedIgnoredDirtyTables, err := ignoredSource.pendingMigrationDirtyTables(ctx, db, dirtyBeforeAll)
if err != nil {
return applied, fmt.Errorf("checking dirty tables against pending ignored migrations: %w", err)
}
if len(touchedIgnoredDirtyTables) > 0 {
// Deliberately a plain, untyped error (unlike the main-source guard
// above, which returns *DirtyTablesError): this check fires mid-pass,
// after the main-source migrations have already applied. A lenient
// caller (embeddeddolt's openReadOnlyCommand / openWorkingSetReconcile
// intents) skipping this and returning as if the open succeeded would
// let a reconcile commit checkpoint a half-applied migration pass.
// The ignored source also tracks bd-internal state (dolt_ignore'd
// tables like ignored_schema_migrations), not expected user data, so
// there is no dirty-commit recovery story to support here the way
// there is for the main-source guard (#4566 scope).View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause; a resume-pending sentinel means re-running MigrateUp should continue the interrupted rekey
- Resolve duplicate ids or constraint violations surfaced by the wrapped error, then re-run
- Avoid killing the process mid-pass; run migrations with the advisory lock (MigrateUpWithLock)
- If the working set is stuck dirty from a partial pass, restore from the last Dolt commit and retry
Defensive patterns
Strategy: retry
Validate before calling
// Check for a pending resume sentinel indicating an interrupted rekey
// (resuming is expected and safe; just ensure storage is writable first)
if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil {
return fmt.Errorf("storage not writable for rekey resume: %w", err)
} Type guard
func isAuxRekeyErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "rekey aux row ids")
} Try / catch
applied, err := schema.MigrateUp(ctx, db)
if isAuxRekeyErr(err) {
// rekey passes are resumable: retry after fixing the wrapped cause
return schema.MigrateUp(ctx, db)
} Prevention
- Use MigrateUpWithLock so crashes mid-rekey are the only resume source
- Avoid interrupting bd during upgrades (no SIGKILL mid-pass)
- Keep adequate disk space for large event/comment table rewrites
When it happens
Trigger: Calling MigrateUp/MigrateUpWithLock where the aux rekey passes fail - duplicate content-derived keys on events/comments/snapshots, resume-sentinel state corruption from a previous crash (bd-578h9.16), or Dolt write errors during the batched UPDATEs.
Common situations: Crashed earlier passes leaving partial aux rekey updates; clones with rows minted between the backfill and the content-id switch; very large event tables hitting timeouts/storage limits mid-pass.
Related errors
- reading aux rekey sentinel: %w
- rekey dependency ids: %w
- failed to migrate credential keys: %w
- failed to update encrypted password for peer %s: %w
- failed to initialize schema: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8c2e5ce934a53785.
Report an issue: GitHub.