gastownhall/beads · error

checking schema migration work: %w

Error message

checking schema migration work: %w

What it means

This error means the 'already converged' fast-path check could not determine whether schema migrations are needed because migrationWorkNeeded itself returned an error (cursor probe, content-hash column probe, or backfill-need probe all failed). The fast path is exactly MigrateUp's own gate and runs first, so this typically indicates a fresh or mid-upgrade database with missing tables, or an unhealthy connection. It aborts the fast path; the locked MigrateUp path should still run.

Source

Thrown at internal/storage/schema/converged.go:58

	// CLI open in uow.openAndInitSchema — pins its schema-init pool with an
	// EMPTY DSN database and only USEs the database after GET_LOCK, so a probe
	// that merely ASKED whether the session was already on databaseName read
	// NULL from DATABASE() and declined on every single invocation: the fast
	// path never fired where it was needed.
	onTarget, qualifier, err := selectTargetDatabase(ctx, db, databaseName, selector)
	if err != nil {
		return false, err
	}
	if !onTarget {
		return false, nil
	}

	// Exactly MigrateUp's own gate, and it runs first: on a fresh or
	// mid-upgrade database it reports work needed from the cursor probe alone,
	// before any statement that could fail against a missing table.
	needed, err := migrationWorkNeeded(ctx, db)
	if err != nil {
		return false, fmt.Errorf("checking schema migration work: %w", err)
	}
	if needed {
		return false, nil
	}

	// MigrateUp re-asserts the canonical dolt_ignore patterns ahead of that
	// gate precisely because an out-of-band-materialized database can arrive
	// with its cursors at-latest and the patterns missing. Read the same
	// question instead of writing it: an under-seeded database is not
	// converged and must take the locked path, which heals and commits it.
	//
	// migrationWorkNeeded has just proved mainSource.atLatest, i.e. the main
	// cursor is at or past mainSource.latest(); every version-gated pattern's
	// flip migration is part of that embedded set, so the gate can be
	// evaluated against latest() with no second cursor read.
	seeded, err := doltIgnoreSeeded(ctx, db, qualifier, mainSource.latest())
	if err != nil {
		return false, err

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run the normal locked MigrateUp path — on a fresh DB this fast-path failure is bypassed by full migration; ensure MigrateUp executes.
  2. Check Dolt server availability and reconnect.
  3. Verify the DB user can read information_schema and the schema tables.
  4. If it persists on an existing DB, read the wrapped cause to find which sub-probe failed and repair that table/schema.

Example fix

// before: abort everything when the fast-path probe fails
needed, err := migrationWorkNeeded(ctx, db)
if err != nil {
	return false, fmt.Errorf("checking schema migration work: %w", err)
}
// after: fall through to the locked migrate path on a missing-table probe failure
needed, err := migrationWorkNeeded(ctx, db)
if err != nil && !isMissingTableErr(err) {
	return false, fmt.Errorf("checking schema migration work: %w", err)
}
if err != nil || needed {
	return false, nil // fall through to full migration
}
Defensive patterns

Strategy: fallback

Validate before calling

// Determine freshness before trusting fast-path probes
var tables int
db.QueryRowContext(ctx, `SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()`).Scan(&tables)
fresh := tables == 0

Try / catch

converged, err := checkConverged(ctx, db)
if err != nil {
	// fast path could not evaluate — fall back to the locked full-migrate path
	converged = false
	err = migrateUpWithLock(ctx, db)
}

Prevention

When it happens

Trigger: alreadyConverged (used by MigrateUpWithLock) calls migrationWorkNeeded, whose atLatest probes or needsBackfilledCustomStatusesCustomTypes hit a SQL error — missing schema tables on a fresh DB, information_schema failure, connection loss, or cancelled context.

Common situations: Opening a brand-new database before any migration ran; connection to the Dolt server dropped at startup; restricted DB user lacking information_schema access; schema damage from an interrupted earlier migration.

Related errors


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