gastownhall/beads · error
schema skew check: %w
Error message
schema skew check: %w
What it means
This error wraps a failure to read the database's current schema version (`CurrentVersion` querying `schema_migrations`) during the forward schema-skew check. The check guards against running a stale binary against a newer database; this wrapper means the version could not be read at all, before any skew comparison was made.
Source
Thrown at internal/storage/schema/schema.go:141
// IsSchemaSkewError reports whether err (or any error it wraps) is a
// *SchemaSkewError.
func IsSchemaSkewError(err error) bool {
var e *SchemaSkewError
return errors.As(err, &e)
}
// checkSchemaSkew queries the DB's current schema version and returns a
// *SchemaSkewError if the DB is ahead of the binary. Returns nil for a fresh
// DB (version=0) or when BD_IGNORE_SCHEMA_SKEW=1 (prints a warning instead).
func checkSchemaSkew(ctx context.Context, db DBConn) error {
// CurrentVersion treats a missing schema_migrations table as version 0, so
// this is safe to call before migrations have created the table: a
// brand-new database (version 0) falls through the no-op check below. That
// matters on the writable open path, where the guard runs before initSchema
// creates the table on a fresh database.
currentVersion, err := CurrentVersion(ctx, db)
if err != nil {
return fmt.Errorf("schema skew check: %w", err)
}
if currentVersion == 0 || currentVersion <= LatestVersion() {
return nil
}
if os.Getenv("BD_IGNORE_SCHEMA_SKEW") == "1" {
fmt.Fprintf(os.Stderr,
"Warning: schema skew ignored — database (v%d) is ahead of binary (v%d); some queries may fail\n",
currentVersion, LatestVersion())
return nil
}
return &SchemaSkewError{DBVersion: currentVersion, BinaryVersion: LatestVersion()}
}
// CheckForwardDrift reports a *SchemaSkewError when the database's schema
// version is AHEAD of the binary's (forward drift). It accepts any DBConn (a
// pooled *sql.DB or a pinned *sql.Conn), so both the read-only store path
// (where MigrateUp is skipped) and the writable open path (where MigrateUp
// no-ops on a forward-drifted DB rather than erroring) can fail fast before aView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause for the real failure (lock, corruption, context deadline)
- Verify the Dolt server is running and `SELECT MAX(version) FROM schema_migrations` executes
- Retry after transient conditions clear (locks, restarts)
- If schema_migrations is corrupt, restore from backup or re-clone
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the version table is readable before the drift check
var v int
if err := db.QueryRowContext(ctx, "SELECT COALESCE(MAX(version),0) FROM schema_migrations").Scan(&v); err != nil {
return fmt.Errorf("cannot read schema version: %w", err)
} Type guard
func isSchemaSkewCheckFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "schema skew check:")
} Try / catch
if err := CheckForwardDrift(ctx, db); err != nil {
if schema.IsSchemaSkewError(err) {
// handle skew (upgrade binary or BD_IGNORE_SCHEMA_SKEW=1)
} else {
// version read itself failed: check server/locks
fmt.Fprintln(os.Stderr, err)
}
} Prevention
- Keep the Dolt server healthy and reachable before opening stores
- Use MigrateUpWithLock to avoid concurrent migration races
- Monitor for corrupted schema_migrations tables in CI
When it happens
Trigger: Calling CheckForwardDrift (or the writable open path that runs checkSchemaSkew) when the `schema_migrations` table exists but is unreadable: connection failure, context cancellation, corrupted table, or a locked Dolt working set.
Common situations: Dolt server crashed or restarting mid-command; read-only open against a corrupt repo; another process holding an exclusive lock; interrupted migration leaving schema_migrations inconsistent.
Related errors
- schema behind-drift check: %w
- 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
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6d18c142e33338c1.
Report an issue: GitHub.