{"record":{"id":"cd3c786fdfd9c8a8","repo":"gastownhall/beads","slug":"custom-types-w","errorCode":null,"errorMessage":"custom_types: %w","messagePattern":"custom_types: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/backfill.go","lineNumber":29,"sourceCode":"\t\"github.com/steveyegge/beads/internal/types\"\n)\n\nfunc ensureBackfilledCustomStatusesCustomTypes(ctx context.Context, db DBConn) (bool, error) {\n\ttypesWrote, err := backfillCustomTypes(ctx, db)\n\tif err != nil {\n\t\treturn typesWrote, fmt.Errorf(\"backfill custom_types: %w\", err)\n\t}\n\tstatusesWrote, err := backfillCustomStatuses(ctx, db)\n\tif err != nil {\n\t\treturn typesWrote || statusesWrote, fmt.Errorf(\"backfill custom_statuses: %w\", err)\n\t}\n\treturn typesWrote || statusesWrote, nil\n}\n\nfunc needsBackfilledCustomStatusesCustomTypes(ctx context.Context, db DBConn) (bool, error) {\n\ttypesNeed, err := needsCustomTypesBackfill(ctx, db)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"custom_types: %w\", err)\n\t}\n\tstatusesNeed, err := needsCustomStatusesBackfill(ctx, db)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"custom_statuses: %w\", err)\n\t}\n\treturn typesNeed || statusesNeed, nil\n}\n\nfunc needsCustomTypesBackfill(ctx context.Context, db DBConn) (bool, error) {\n\tvar count int\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM custom_types\").Scan(&count); err != nil {\n\t\treturn false, err\n\t}\n\tif count > 0 {\n\t\treturn false, nil\n\t}\n\n\tvar value string","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/backfill.go#L11-L47","documentation":"Wrapper from needsBackfilledCustomStatusesCustomTypes when the probe needsCustomTypesBackfill fails. This probe runs as part of migrationWorkNeeded (MigrateUp's work-detection gate) and simply runs SELECT COUNT(*) FROM custom_types plus a config lookup; any SQL error here is wrapped so the caller knows migration gating itself couldn't be evaluated.","triggerScenarios":"needsCustomTypesBackfill's SELECT COUNT(*) FROM custom_types or SELECT value FROM config WHERE key='types.custom' errors — usually because custom_types (or config) doesn't exist yet on a fresh or mid-upgrade database, or the connection/context failed.","commonSituations":"Fresh database probed before migrations created the tables; connection dropped during startup; restricted user lacking SELECT; Dolt server unavailable when `bd` opens the database.","solutions":["Let MigrateUp proceed and create the schema — on a fresh DB the missing table is expected; complete the migration flow.","Check Dolt server connectivity and retry opening the database.","Verify SELECT privileges on custom_types and config.","If the table should exist, run `bd doctor` schema checks or restore from backup."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Check base tables exist before probing migration state\nvar n int\nerr := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN ('custom_types','config')`).Scan(&n)\nif err == nil && n < 2 {\n\t// fresh database: skip probes, go straight to MigrateUp\n}","typeGuard":null,"tryCatchPattern":"err := openAndMigrate(ctx)\nif err != nil && strings.Contains(err.Error(), \"custom_types:\") {\n\tif isMissingTableErr(err) || isTransient(err) {\n\t\terr = openAndMigrate(ctx) // full migration creates the missing table\n\t}\n}","preventionTips":["On a fresh database, always invoke the full MigrateUp rather than only read/probe paths","Verify DB connectivity before running schema-dependent commands","Grant the user SELECT on information_schema and config","Retry opens after transient Dolt server unavailability"],"tags":["database","migration","probe"],"backgroundTag":"migration-gate-probe-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}