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

  1. Retry the query — it is usually transient (the next call gets a fresh pooled connection).
  2. Configure the pool with connection lifetimes (SetConnMaxLifetime below server wait_timeout) and enable driver keepalives to avoid stale connections.
  3. Check Cloud SQL logs for instance restarts or connection kills during the request window.
  4. Verify network stability (VPC connector, NAT, proxy) between the runtime and the instance.
  5. 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

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


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/3453b0100c6a9a5b. Report an issue: GitHub.