gastownhall/beads · warning
clearing aux rekey sentinel: %w
Error message
clearing aux rekey sentinel: %w
What it means
This error wraps a failure to delete the 'aux rekey in progress' sentinel row from local_metadata after an auxiliary-table ID re-key pass completes. The rekey already finished; only the cleanup DELETE failed, so the sentinel remains and the next migration run will resume/re-run the pass. It indicates a write failure against the local_metadata table (connection loss, lock timeout, permissions, or cancellation) at the very end of a migration pass.
Source
Thrown at internal/storage/schema/aux_row_id_backfill.go:259
}
// Sentinel before the first UPDATE: a crash anywhere in the rewrite
// leaves it set, so the next pass resumes (the rewrite is idempotent)
// instead of recording the marker over partially re-keyed rows.
if err := setAuxRekeyInProgress(ctx, db, pass.sentinelKey); err != nil {
return false, fmt.Errorf("recording aux rekey sentinel: %w", err)
}
wrote := false
for _, t := range auxRekeyTables {
w, err := rekeyAuxRowTable(ctx, db, t)
wrote = wrote || w
if err != nil {
return wrote, fmt.Errorf("%s: %w", t.name, err)
}
}
if err := clearAuxRekeyInProgress(ctx, db, pass.sentinelKey); err != nil {
return wrote, fmt.Errorf("clearing aux rekey sentinel: %w", err)
}
return wrote, nil
}
// rekeyAuxRowTable re-derives the ids of one table. The whole table is grouped
// by content digest; each digest's rows take the deterministic ids for
// ordinals 0..n-1. A row already holding one of its group's target ids keeps
// it (idempotence: re-running never swaps ids within a group), and the
// remaining rows take the remaining targets in sorted-current-id order. Across
// clones that assignment may permute within a group of exact-duplicate rows,
// but duplicates are interchangeable and the id set is identical, so the
// merged result still converges.
func rekeyAuxRowTable(ctx context.Context, db DBConn, t auxRekeyTable) (bool, error) {
// Skip cleanly if the table or its id column isn't present (older or partial
// schema): nothing to re-key. After MigrateUp's main pass the id column is
// CHAR(36) on any schema this runs against (0037 precedes the marker).
hasID, err := columnExists(ctx, db, t.name, "id")
if err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the migration (MigrateUp re-invokes the pass because the sentinel is still set; the rekey is idempotent and will converge and clear the sentinel this time).
- Check DB connectivity and that the Dolt server is up, then retry.
- Verify the DB user has DELETE privilege on local_metadata.
- Check the context isn't being cancelled prematurely by the caller (timeouts, signal handling).
Example fix
// before: sentinel left behind after transient DELETE failure
if err := clearAuxRekeyInProgress(ctx, db, pass.sentinelKey); err != nil {
return wrote, fmt.Errorf("clearing aux rekey sentinel: %w", err)
}
// after: best-effort cleanup, sentinel is safe to resume next run
if err := clearAuxRekeyInProgress(ctx, db, pass.sentinelKey); err != nil {
log.Printf("warning: clearing aux rekey sentinel %s: %v (will resume next run)", pass.sentinelKey, err)
} Defensive patterns
Strategy: retry
Validate before calling
// Before triggering migration, check the sentinel table is accessible
var n int
if err := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM local_metadata").Scan(&n); err != nil {
return fmt.Errorf("local_metadata not accessible: %w", err)
} Try / catch
result, err := runMigration(ctx)
if err != nil && strings.Contains(err.Error(), "clearing aux rekey sentinel") {
// cleanup-only failure: re-run; the pass is idempotent and will clear the sentinel
result, err = runMigration(context.Background())
} Prevention
- Don't cancel contexts mid-migration; use a background context for the migration phase
- Ensure the DB user has full privileges on local_metadata
- Run migrations while the Dolt server is stable (no restarts or maintenance windows)
- Re-run migrations after any interruption — sentinel logic makes passes resumable
When it happens
Trigger: rekeyAuxRowIDsPending calls clearAuxRekeyInProgress (DELETE FROM local_metadata WHERE key = <sentinelKey>) after the rekey pass succeeds; the DELETE fails due to a dropped/cancelled context, DB connection loss, insufficient privileges on local_metadata, or a lock conflict during migration.
Common situations: Network blip or Dolt server restart mid-migration; context cancelled by the user Ctrl-C'ing a long `bd` migration; local_metadata table locked by another session; running with a DB user lacking DELETE privilege.
Related errors
- unstaging ignored migration tables: %w
- failed to migrate credential keys: %w
- failed to update encrypted password for peer %s: %w
- failed to initialize schema: %w
- failed to rebuild pool after migration: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b106c33cc738bdba.
Report an issue: GitHub.