googleapis/mcp-toolbox · error
unable to retrieve rows column name: %w
Error message
unable to retrieve rows column name: %w
What it means
This error is thrown when results.Columns() fails after a successful QueryContext in RunSQL. Columns() reads the result set metadata from the MySQL driver; failing here usually means the connection died between query submission and metadata retrieval, or the driver returned an unexpected protocol state.
Source
Thrown at internal/sources/cloudsqlmysql/cloud_sql_mysql.go:143
func (s *Source) RetrieveSourceVersion(ctx context.Context) (string, error) {
var version string
if err := s.MySQLPool().QueryRowContext(ctx, "SELECT VERSION()").Scan(&version); err != nil {
return "", err
}
return version, nil
}
func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {
statement = sqlcommenter.PrependComment(ctx, statement, SourceType, s.SQLCommenter)
results, err := s.MySQLPool().QueryContext(ctx, statement, params...)
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)
}
defer results.Close()
cols, err := results.Columns()
if err != nil {
return nil, fmt.Errorf("unable to retrieve rows column name: %w", err)
}
// create an array of values for each column, which can be re-used to scan each row
rawValues := make([]any, len(cols))
values := make([]any, len(cols))
for i := range rawValues {
values[i] = &rawValues[i]
}
colTypes, err := results.ColumnTypes()
if err != nil {
return nil, fmt.Errorf("unable to get column types: %w", err)
}
out := []any{}
for results.Next() {
err := results.Scan(values...)
if err != nil {View on GitHub (pinned to 8cc6e09de2)
Solutions
- Retry the query — it is usually transient (the next call gets a fresh pooled connection).
- Configure the pool with connection lifetimes (SetConnMaxLifetime below server wait_timeout) and enable driver keepalives to avoid stale connections.
- Check Cloud SQL logs for instance restarts or connection kills during the request window.
- Verify network stability (VPC connector, NAT, proxy) between the runtime and the instance.
- Update the go-sql-driver/mysql dependency if errors persist across driver versions.
Example fix
// before
pool, err := sql.Open("mysql", dsn)
// after
pool.SetConnMaxLifetime(5 * time.Minute)
pool.SetConnMaxIdleTime(2 * time.Minute) Defensive patterns
Strategy: retry
Validate before calling
func ensureHealthyPool(db *sql.DB) error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("pool unhealthy before query: %w", err)
}
return nil
} Type guard
func isTransientConnectionLoss(err error) bool {
msg := err.Error()
return strings.Contains(msg, "broken pipe") ||
strings.Contains(msg, "connection refused") ||
strings.Contains(msg, "bad connection") ||
strings.Contains(msg, "driver: bad connection") ||
errors.Is(err, io.EOF)
} Try / catch
var result any
var err error
for attempt := 0; attempt < 2; attempt++ {
result, err = src.RunSQL(ctx, statement, params)
if err == nil {
break
}
if !isTransientConnectionLoss(err) || !strings.Contains(err.Error(), "column name") {
break // not retryable
}
time.Sleep(200 * time.Millisecond) // fresh pooled connection
} Prevention
- Set pool.SetConnMaxLifetime below the MySQL server's wait_timeout so idle connections are retired before the server kills them.
- Call PingContext (or set connection validation) before reusing long-idle pools.
- Monitor Cloud SQL for restarts/failovers and add retry logic in callers of RunSQL.
- Keep the go-sql-driver/mysql driver up to date.
- Avoid very long-running queries that hold result sets across network-sensitive windows.
When it happens
Trigger: Calling RunSQL when the MySQL connection is dropped between QueryContext and Columns() (network interruption, server wait_timeout kill, instance restart), or a driver-level protocol error while fetching result metadata.
Common situations: Long-idle pooled connections killed by the server's wait_timeout, Cloud SQL instance restart/failover mid-request, transient network blips between the app and the instance, very large result metadata over an unstable link.
Related errors
- unable to get column types: %w
- unable to create pool: %w
- unable to connect successfully: %w
- unable to execute query: %w
- unable to parse row: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/3453b0100c6a9a5b.
Report an issue: GitHub.