googleapis/mcp-toolbox · error

unable to parse row: %w

Error message

unable to parse row: %w

What it means

While streaming query results, RunSQL calls results.Values() for each row. This error wraps a failure decoding a row's column values into Go representations (pgx type decoding), which happens after the query has started successfully.

Source

Thrown at internal/sources/alloydbpg/alloydb_pg.go:131

func (s *Source) PostgresPool() *pgxpool.Pool {
	return s.Pool
}

func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {
	statement = sqlcommenter.PrependComment(ctx, statement, SourceType, s.SQLCommenter)
	results, err := s.Pool.Query(ctx, statement, params...)
	if err != nil {
		return nil, fmt.Errorf("unable to execute query: %w", err)
	}
	defer results.Close()

	fields := results.FieldDescriptions()
	out := []any{}
	for results.Next() {
		v, err := results.Values()
		if err != nil {
			return nil, fmt.Errorf("unable to parse row: %w", err)
		}
		row := orderedmap.Row{}
		for i, f := range fields {
			val := sources.NormalizeValue(v[i], f.DataTypeOID)
			row.Add(f.Name, val)
		}
		out = append(out, row)
	}
	// this will catch actual query execution errors
	if err := results.Err(); err != nil {
		return nil, fmt.Errorf("unable to execute query: %w", err)
	}
	return out, nil
}

func getOpts(ipType, userAgent string, useIAM bool) ([]alloydbconn.Option, error) {
	opts := []alloydbconn.Option{alloydbconn.WithUserAgent(userAgent)}
	switch strings.ToLower(ipType) {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Identify the failing column from the wrapped error and cast it in SQL (e.g. `col::text`).
  2. Avoid SELECT * on tables with exotic custom types; select needed columns explicitly.
  3. Register custom types or update the pgx/pgconn driver versions for better type coverage.
  4. Retry the query if the error was transient (e.g. during a concurrent DDL change).

Example fix

// before
SELECT * FROM sensors;
// after
SELECT id, name, reading::text AS reading FROM sensors;
Defensive patterns

Strategy: try-catch

Validate before calling

-- Check for exotic column types before SELECT *
SELECT column_name, data_type, udt_name FROM information_schema.columns
WHERE table_name = 'my_table' AND udt_name NOT IN (
  'int2','int4','int8','float4','float8','numeric','bool','text','varchar','bpchar','date','timestamp','timestamptz','uuid','bytea','json','jsonb');

Try / catch

out, err := src.RunSQL(ctx, stmt, params)
if err != nil && strings.Contains(err.Error(), "unable to parse row") {
    // retry with casts to text for custom-typed columns
    stmt = rewriteWithCasts(stmt)
    out, err = src.RunSQL(ctx, stmt, params)
}

Prevention

When it happens

Trigger: A result row contains a column value that pgx cannot decode into its expected Go type — typically custom/composite/enum types with unusual OIDs, corrupted values, or driver-type-mapping mismatches.

Common situations: Selecting exotic custom types or domains, tables with user-defined types not registered with the driver, or bytea/geometry values with encoding issues during result streaming.

Understand the failure class

Related errors


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