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

  1. Inspect custom_types for NULL or non-string name values and delete or repair those rows
  2. Re-insert correct type rows via SetConfig so the normalized table is rewritten cleanly
  3. Re-apply NOT NULL constraints on custom_types.name
  4. Run `bd doctor` to verify custom-type table consistency against the config string
  5. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/e2d0a2e8fd95043d. Report an issue: GitHub.