{"record":{"id":"0809a555988fe728","repo":"gastownhall/beads","slug":"custom-statuses-w","errorCode":null,"errorMessage":"custom_statuses: %w","messagePattern":"custom_statuses: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/backfill.go","lineNumber":33,"sourceCode":"\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\n\terr := db.QueryRowContext(ctx, \"SELECT `value` FROM config WHERE `key` = 'types.custom'\").Scan(&value)\n\tif err == sql.ErrNoRows {\n\t\treturn false, nil\n\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/backfill.go#L15-L51","documentation":"Wrapper from needsBackfilledCustomStatusesCustomTypes when the probe needsCustomStatusesBackfill fails, during migrationWorkNeeded evaluation. The probe issues SELECT COUNT(*) FROM custom_statuses and a config lookup; any SQL error is wrapped so callers of migrationWorkNeeded can distinguish 'work needed' from 'cannot determine'.","triggerScenarios":"needsCustomStatusesBackfill's SELECT COUNT(*) FROM custom_statuses or its config read fails — missing table on a fresh or partial database, cancelled context, connection loss, or missing SELECT privilege.","commonSituations":"Opening a brand-new database before migrations run; mid-upgrade database missing custom_statuses; network interruption to the Dolt server; DB user restrictions.","solutions":["Complete the MigrateUp flow so all tables are created, then re-open.","Verify Dolt server connectivity and retry.","Grant SELECT on custom_statuses and config to the DB user.","Check the wrapped cause for the precise statement and schema state."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Detect a fresh database before probing backfill need\nvar n int\nerr := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'custom_statuses'`).Scan(&n)\nif err == nil && n == 0 {\n\t// schema not created yet — run MigrateUp instead of probing\n}","typeGuard":null,"tryCatchPattern":"err := openAndMigrate(ctx)\nif err != nil && strings.Contains(err.Error(), \"custom_statuses:\") {\n\tif isMissingTableErr(err) || isTransient(err) {\n\t\terr = openAndMigrate(ctx)\n\t}\n}","preventionTips":["Complete the migration chain before read-only probes on a new DB","Ensure SELECT privileges on custom_statuses and config","Keep the Dolt server reachable during CLI startup","Re-run after transient failures; probes are read-only and safe to repeat"],"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"}