gastownhall/beads · error
db: GetCustomTypes: scan custom_types: %w
Error message
db: GetCustomTypes: scan custom_types: %w
What it means
This error wraps a rows.Scan failure while iterating the custom_types result set in readCustomTypesTable. The query succeeded but a name column could not be decoded into a string — most commonly because a row holds NULL or a non-string value in the name column.
Source
Thrown at internal/storage/domain/db/config.go:160
}
return unionWithYAMLCustomTypes(fromDB, config.GetCustomTypesFromYAML()), nil
}
func (r *configSQLRepositoryImpl) readCustomTypesTable(ctx context.Context) ([]string, error) {
rows, err := r.runner.QueryContext(ctx, "SELECT name FROM custom_types ORDER BY name")
if err != nil {
if dberrors.IsTableNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("db: GetCustomTypes: query custom_types: %w", err)
}
defer rows.Close()
var out []string
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, fmt.Errorf("db: GetCustomTypes: scan custom_types: %w", err)
}
if name = strings.TrimSpace(name); name != "" {
out = append(out, name)
}
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("db: GetCustomTypes: read custom_types: %w", err)
}
return out, nil
}
func (r *configSQLRepositoryImpl) readCustomTypesConfig(ctx context.Context) ([]string, error) {
value, err := r.GetConfig(ctx, "types.custom")
if err != nil {
return nil, fmt.Errorf("db: GetCustomTypes: %w", err)
}
return issueops.ParseTypesConfigValue(value), nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Inspect custom_types for NULL or non-string name values and delete or repair those rows
- Re-insert correct type rows via SetConfig so the normalized table is rewritten cleanly
- Re-apply NOT NULL constraints on custom_types.name
- Run `bd doctor` to verify custom-type table consistency against the config string
- Restore from a known-good backup if the table was corrupted externally
Defensive patterns
Strategy: validation
Validate before calling
rows, _ := db.Query("SELECT COUNT(*) FROM custom_types WHERE name IS NULL")
var bad int
rows.Scan(&bad)
if bad > 0 {
return fmt.Errorf("%d custom_types rows have NULL name; repair before reading", bad)
} Try / catch
if _, err := repo.GetCustomTypes(ctx); err != nil && strings.Contains(err.Error(), "scan") {
// NULL/malformed name row: delete bad rows and re-sync via SetConfig
return repairCustomTypes(ctx)
} Prevention
- Insert custom types only via SetConfig so names are validated and non-null
- Keep NOT NULL on custom_types.name through migrations
- Avoid direct SQL writes into the Dolt database
- Run `bd doctor` to verify type-table consistency after external modifications
When it happens
Trigger: GetCustomTypes → readCustomTypesTable when rows.Scan(&name) fails: a custom_types row has NULL name, or the driver cannot convert the column value to string.
Common situations: Externally inserted custom_types rows with NULL names (bypassing the SyncConfigTables path); schema drift removing NOT NULL from custom_types.name; manual SQL edits to the Dolt database.
Related errors
- db: GetAllConfig: scan: %w
- get labels: scan: %w
- get labels for issues: scan: %w
- ErrScan
- failed to scan dependency keys: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e2d0a2e8fd95043d.
Report an issue: GitHub.