{"record":{"id":"6d18c142e33338c1","repo":"gastownhall/beads","slug":"schema-skew-check-w","errorCode":null,"errorMessage":"schema skew check: %w","messagePattern":"schema skew check: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/schema.go","lineNumber":141,"sourceCode":"// IsSchemaSkewError reports whether err (or any error it wraps) is a\n// *SchemaSkewError.\nfunc IsSchemaSkewError(err error) bool {\n\tvar e *SchemaSkewError\n\treturn errors.As(err, &e)\n}\n\n// checkSchemaSkew queries the DB's current schema version and returns a\n// *SchemaSkewError if the DB is ahead of the binary. Returns nil for a fresh\n// DB (version=0) or when BD_IGNORE_SCHEMA_SKEW=1 (prints a warning instead).\nfunc checkSchemaSkew(ctx context.Context, db DBConn) error {\n\t// CurrentVersion treats a missing schema_migrations table as version 0, so\n\t// this is safe to call before migrations have created the table: a\n\t// brand-new database (version 0) falls through the no-op check below. That\n\t// matters on the writable open path, where the guard runs before initSchema\n\t// creates the table on a fresh database.\n\tcurrentVersion, err := CurrentVersion(ctx, db)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"schema skew check: %w\", err)\n\t}\n\tif currentVersion == 0 || currentVersion <= LatestVersion() {\n\t\treturn nil\n\t}\n\tif os.Getenv(\"BD_IGNORE_SCHEMA_SKEW\") == \"1\" {\n\t\tfmt.Fprintf(os.Stderr,\n\t\t\t\"Warning: schema skew ignored — database (v%d) is ahead of binary (v%d); some queries may fail\\n\",\n\t\t\tcurrentVersion, LatestVersion())\n\t\treturn nil\n\t}\n\treturn &SchemaSkewError{DBVersion: currentVersion, BinaryVersion: LatestVersion()}\n}\n\n// CheckForwardDrift reports a *SchemaSkewError when the database's schema\n// version is AHEAD of the binary's (forward drift). It accepts any DBConn (a\n// pooled *sql.DB or a pinned *sql.Conn), so both the read-only store path\n// (where MigrateUp is skipped) and the writable open path (where MigrateUp\n// no-ops on a forward-drifted DB rather than erroring) can fail fast before a","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/schema.go#L123-L159","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure the version table is readable before the drift check\nvar v int\nif err := db.QueryRowContext(ctx, \"SELECT COALESCE(MAX(version),0) FROM schema_migrations\").Scan(&v); err != nil {\n\treturn fmt.Errorf(\"cannot read schema version: %w\", err)\n}","typeGuard":"func isSchemaSkewCheckFailure(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"schema skew check:\")\n}","tryCatchPattern":"if err := CheckForwardDrift(ctx, db); err != nil {\n\tif schema.IsSchemaSkewError(err) {\n\t\t// handle skew (upgrade binary or BD_IGNORE_SCHEMA_SKEW=1)\n\t} else {\n\t\t// version read itself failed: check server/locks\n\t\tfmt.Fprintln(os.Stderr, err)\n\t}\n}","preventionTips":["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"],"tags":["schema","migration","version-check"],"backgroundTag":"schema-version-read-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}