gastownhall/beads · error

reading aux rekey sentinel: %w

Error message

reading aux rekey sentinel: %w

What it means

This error wraps a failure while reading the aux-rekey resume sentinel (anyAuxRekeyResumePending) during MigrateUp. The sentinel records whether a previous migration pass crashed mid aux-row rekey; MigrateUp needs it to decide which dirty tables to exempt from its guards. If the sentinel cannot be read, the migration aborts rather than risk misclassifying pre-existing dirty tables.

Source

Thrown at internal/storage/schema/schema.go:629

	// (so nothing else rides into the commit) and before the first step runs.
	if seedChanged {
		if err := commitSeededDoltIgnore(ctx, db); err != nil {
			return 0, err
		}
	}
	dirtyBefore, err := committableDirtyTables(ctx, db)
	if err != nil {
		return 0, fmt.Errorf("reading pre-migration status: %w", err)
	}
	delete(dirtyBefore, "dolt_ignore")
	// A previous pass that crashed mid-aux-rekey left its partial UPDATEs
	// dirty in the working set with the in-progress sentinel still recorded
	// (bd-578h9.16). Those tables are this pass's own migration state, not
	// pre-existing user writes: dropping them from dirtyBefore exempts them
	// from the changed-signature guard (the resumed rekey is about to change
	// them) and lets stageSchemaTables commit them with the rest of the pass.
	if resuming, err := anyAuxRekeyResumePending(ctx, db); err != nil {
		return 0, fmt.Errorf("reading aux rekey sentinel: %w", err)
	} else if resuming {
		for _, t := range auxRekeyTables {
			delete(dirtyBefore, t.name)
		}
	}
	touchedDirtyTables, err := mainSource.pendingMigrationDirtyTables(ctx, db, dirtyBefore)
	if err != nil {
		return 0, fmt.Errorf("checking dirty tables against pending migrations: %w", err)
	}
	if len(touchedDirtyTables) > 0 {
		return 0, &DirtyTablesError{Tables: touchedDirtyTables}
	}
	dirtyBeforeSignatures, err := dirtyTableSignatures(ctx, db, dirtyBefore)
	if err != nil {
		return 0, fmt.Errorf("reading pre-migration dirty table diffs: %w", err)
	}
	// Captured before the main migrations run: the aux re-key uses it to
	// distinguish the lineage's first rekey-aware migration (run the pass)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix the wrapped cause returned after this message (query/IO error reading the sentinel)
  2. Verify the marker/ignored-schema-migrations storage exists and is readable in this clone
  3. If the database is a broken partial copy, re-clone or restore from a good commit and re-run migrations
  4. Re-run MigrateUp once storage access is healthy; the sentinel read is retried on each pass
Defensive patterns

Strategy: validation

Validate before calling

// Verify marker storage is readable before migrating
if _, err := db.QueryContext(ctx,
    "SELECT * FROM ignored_schema_migrations LIMIT 1"); err != nil {
    return fmt.Errorf("ignored migration marker unreadable: %w", err)
}

Type guard

func isAuxRekeySentinelErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "reading aux rekey sentinel")
}

Try / catch

if _, err := schema.MigrateUp(ctx, db); err != nil {
    if isAuxRekeySentinelErr(err) {
        return fmt.Errorf("cannot determine crash-recovery state: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling MigrateUp (directly or via MigrateUpWithLock) on a database where the query that reads the aux rekey in-progress marker fails - e.g. the marker storage table/system doc is unreadable, corrupt, or the Dolt connection errors mid-read.

Common situations: Resuming after a crashed migration pass (bd-578h9.16 scenario) where the marker table itself is damaged; a partially copied database missing the sentinel storage; storage engine errors during the read.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/7b1613a2d126e35f. Report an issue: GitHub.