{"record":{"id":"3117977971e9156d","repo":"gastownhall/beads","slug":"db-getcustomtypes-query-custom-types-w","errorCode":null,"errorMessage":"db: GetCustomTypes: query custom_types: %w","messagePattern":"db: GetCustomTypes: query custom_types: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/config.go","lineNumber":153,"sourceCode":"\tfromDB := fromTable\n\tif len(fromDB) == 0 {\n\t\tfromConfig, err := r.readCustomTypesConfig(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfromDB = fromConfig\n\t}\n\n\treturn unionWithYAMLCustomTypes(fromDB, config.GetCustomTypesFromYAML()), nil\n}\n\nfunc (r *configSQLRepositoryImpl) readCustomTypesTable(ctx context.Context) ([]string, error) {\n\trows, err := r.runner.QueryContext(ctx, \"SELECT name FROM custom_types ORDER BY name\")\n\tif err != nil {\n\t\tif dberrors.IsTableNotExist(err) {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"db: GetCustomTypes: query custom_types: %w\", err)\n\t}\n\tdefer rows.Close()\n\tvar out []string\n\tfor rows.Next() {\n\t\tvar name string\n\t\tif err := rows.Scan(&name); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"db: GetCustomTypes: scan custom_types: %w\", err)\n\t\t}\n\t\tif name = strings.TrimSpace(name); name != \"\" {\n\t\t\tout = append(out, name)\n\t\t}\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"db: GetCustomTypes: read custom_types: %w\", err)\n\t}\n\treturn out, nil\n}\n","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/config.go#L135-L171","documentation":"This error wraps failure of the SELECT used by readCustomTypesTable to load custom issue types from the custom_types table. A missing table is handled gracefully (IsTableNotExist returns nil, nil) so this error only fires for genuine query failures — locking, connection, context, or driver errors. GetCustomTypes treats an empty/missing table as a signal to fall back to the config string.","triggerScenarios":"GetCustomTypes → readCustomTypesTable when SELECT name FROM custom_types ORDER BY name fails with an error other than table-not-exist: database locked, connection dropped, context canceled, or a driver error unrelated to table existence.","commonSituations":"Listing issue types on a repo whose Dolt database is locked by another process; context deadline exceeded during schema listing; corrupted database; a driver error misreported as something other than table-not-exist on very old schemas.","solutions":["Check the wrapped cause; if it is a table-existence variant on an old schema, run migration","Clear competing database locks and retry","Retry with a longer context timeout if the deadline was exceeded","Verify database integrity; restore from backup if corrupted","Note that a missing table is NOT this error — empty result triggers the config-string fallback instead"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if !tableExists(ctx, \"custom_types\") {\n\t// repository itself falls back to the config string; callers may do the same\n}","typeGuard":null,"tryCatchPattern":"types, err := repo.GetCustomTypes(ctx)\nif err != nil {\n\tif isTransient(err) {\n\t\ttypes, err = repo.GetCustomTypes(ctx) // one retry\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading custom types: %w\", err)\n\t}\n}","preventionTips":["A missing custom_types table is not this error — the repo falls back to the config string automatically","Migrate schema after bd upgrades","Retry transient lock/connection failures; type listing is read-only","Use adequate context timeouts on schema queries"],"tags":["database","dolt","query-failed","custom-types"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}