gastownhall/beads · error
checking schema migration work: %w
Error message
checking schema migration work: %w
What it means
This error wraps a failure of `migrationWorkNeeded` — the pre-flight query that decides whether any schema migrations must run. MigrateUp calls it before doing any work so it can short-circuit and still commit seeded dolt_ignore patterns; failing here aborts the whole migration pass.
Source
Thrown at internal/storage/schema/schema.go:577
func MigrateUpTo(ctx context.Context, db DBConn, maxVersion int) (int, error) {
applied, _, err := mainSource.migrate(ctx, db, maxVersion)
return applied, err
}
func MigrateUp(ctx context.Context, db DBConn) (int, error) {
// Re-assert the canonical dolt_ignore patterns before anything else, and
// in particular before the migrationWorkNeeded short-circuit: a database
// whose migration cursors arrived at-latest without executing the seeding
// migrations (out-of-band table copy) reports no work needed and
// would otherwise never be healed.
seedChanged, err := seedDoltIgnorePatterns(ctx, db)
if err != nil {
return 0, err
}
needed, err := migrationWorkNeeded(ctx, db)
if err != nil {
return 0, fmt.Errorf("checking schema migration work: %w", err)
}
if !needed {
// No migration pass will run, so nothing downstream commits the seed:
// it would sit as an uncommitted working-set diff until an unrelated
// write/pull sweeps it into its commit (and a read-only repo carries
// it indefinitely). Commit it here, scoped and labeled, so the
// out-of-band-copy heal converges in one pass.
if seedChanged {
if err := commitSeededDoltIgnore(ctx, db); err != nil {
return 0, err
}
}
return 0, nil
}
dirtyBeforeAll, err := dirtyTables(ctx, db, false)
if err != nil {
return 0, fmt.Errorf("reading pre-migration status: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause for the underlying SQL failure
- Ensure no other bd process is migrating concurrently (the advisory lock path serializes, but direct calls bypass it)
- Verify schema_migrations is readable and the Dolt server is healthy
- Retry MigrateUp once transient conditions clear
Example fix
// before: concurrent migrate calls collide err := schema.MigrateUp(ctx, db) // after: use the locked wrapper err := schema.MigrateUpWithLock(ctx, db)
Defensive patterns
Strategy: retry
Validate before calling
// verify schema state is queryable before a migration pass
if _, err := db.ExecContext(ctx, "SELECT 1 FROM schema_migrations LIMIT 1"); err != nil {
return fmt.Errorf("schema not queryable: %w", err)
} Try / catch
_, err := schema.MigrateUp(ctx, db)
if err != nil && strings.Contains(err.Error(), "checking schema migration work") {
// transient server/lock issue: back off and retry once
time.Sleep(backoff)
_, err = schema.MigrateUpWithLock(ctx, db)
} Prevention
- Prefer MigrateUpWithLock so concurrent processes serialize
- Retry transient server errors with backoff
- Check context deadlines — long networked Dolt reads can time out
When it happens
Trigger: Calling MigrateUp (directly or via MigrateUpWithLock) when the migration-work check queries schema state (current version vs. available migrations) and the underlying SQL fails — unreadable schema_migrations, locked working set, or context cancellation.
Common situations: Dolt server unavailable or restarting; concurrent bd process holding the migration or working-set lock; corrupt schema_migrations table; context deadline exceeded on slow networked Dolt.
Related errors
- clone from %s succeeded, but the database needs %d schema %s
- legacy SQLite release marker: %w
- legacy SQLite schema drift in %s hidden column
- legacy SQLite schema drift in %s
- legacy SQLite issue %s uses unsupported removed fields
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/15da97ce9218d3b9.
Report an issue: GitHub.