{"record":{"id":"37500fcf4f11e706","repo":"gastownhall/beads","slug":"uow-team-server-schema-check-w","errorCode":null,"errorMessage":"uow: team-server schema check: %w","messagePattern":"uow: team-server schema check: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/uow/dolt_sql_provider.go","lineNumber":256,"sourceCode":"\n// verifyTeamServerSchema is the team-server open path: the schema is owned by\n// beads-team-server (bts), so bd never creates the database or migrates. It\n// attaches to the existing database and verifies the schema version, then the\n// project identity — identity is checked only after the schema check proves the\n// metadata table exists at this binary's version.\nfunc (p *doltSQLProvider) verifyTeamServerSchema(ctx context.Context, conn *sql.Conn, database string) error {\n\tddl := db.NewDDLSQLRepository(conn)\n\tif err := ddl.UseDatabase(ctx, database); err != nil {\n\t\tif isSerializationError(err) {\n\t\t\treturn fmt.Errorf(\"uow: switching to database: %w\", err)\n\t\t}\n\t\treturn backoff.Permanent(fmt.Errorf(\n\t\t\t\"uow: database %q not found — the schema is managed by beads-team-server; ask your operator to run 'bts init' first: %w\",\n\t\t\tdatabase, err))\n\t}\n\tif err := checkTeamServerSchema(ctx, conn, database); err != nil {\n\t\tif isSerializationError(err) {\n\t\t\treturn fmt.Errorf(\"uow: team-server schema check: %w\", err)\n\t\t}\n\t\treturn backoff.Permanent(err)\n\t}\n\tif err := checkTeamServerIdentity(ctx, conn, database, p.expectedProjectID); err != nil {\n\t\tif isSerializationError(err) {\n\t\t\treturn fmt.Errorf(\"uow: team-server identity check: %w\", err)\n\t\t}\n\t\treturn backoff.Permanent(err)\n\t}\n\treturn nil\n}\n\n// attachPreviewDatabase is the preview open path: attach to the database that is\n// already there and stop. No CreateDatabase, no MigrateUpWithLock — a --dry-run\n// or --inspect that migrated the workspace before rendering its plan would be the\n// exact side effect the flag exists to prevent.\nfunc (p *doltSQLProvider) attachPreviewDatabase(ctx context.Context, conn *sql.Conn, database string) error {\n\tddl := db.NewDDLSQLRepository(conn)","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/dolt_sql_provider.go#L238-L274","documentation":"After the USE succeeds, verifyTeamServerSchema calls checkTeamServerSchema to verify the team-server database's schema version matches this binary. A serialization-class failure there is wrapped as 'uow: team-server schema check: %w' and returned bare so the backoff loop retries; non-serialization failures are terminal (returned unwrapped as permanent).","triggerScenarios":"initSchemaAttempt (teamServer=true); the metadata/schema-version query inside checkTeamServerSchema fails with a serialization error on the contended shared server, e.g. while 'bts init' or an upgrade is still in flight.","commonSituations":"Clients connecting while the operator is mid-'bts init' or mid schema upgrade; Dolt serialization conflicts from concurrent metadata reads/writes on a loaded team server.","solutions":["Retry — backoff will re-run the check once concurrent writes settle.","Ensure 'bts init' (or the schema upgrade) fully completed before clients connect.","Check the team server's schema version is compatible with this bd binary.","Inspect the wrapped cause if the check keeps failing."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// confirm the team server's schema version is current before connecting clients\nvar version string\nerr := adminConn.QueryRowContext(ctx,\n    \"SELECT value FROM metadata WHERE key = 'schema_version'\").Scan(&version)\nif err != nil { return fmt.Errorf(\"cannot read team-server schema version: %w\", err) }\nif version != schema.ExpectedVersion {\n    return fmt.Errorf(\"team-server schema %s != binary expects %s; run bts upgrade\", version, schema.ExpectedVersion)\n}","typeGuard":"if uow.IsSerializationError(err) { /* transient check failure — retryable */ }","tryCatchPattern":"err := provider.Open(ctx, cfg)\nif err != nil {\n    if uow.IsSerializationError(err) {\n        // team-server metadata contended — retry with backoff\n        return backoff.Retry(openFn, bo)\n    }\n    return err\n}","preventionTips":["Schedule bts schema upgrades outside client peak hours.","Block client rollouts until 'bts init'/upgrade reports complete.","Keep bd client versions compatible with the team server's schema version.","Alert on repeated serialization failures during metadata checks."],"tags":["database","team-server","schema","serialization","retry"],"backgroundTag":"schema-version-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}