googleapis/mcp-toolbox · error

unable to parse row: %w

Error message

unable to parse row: %w

What it means

This error wraps a failure that occurred while iterating over result rows returned by a SQL query executed through the pgx/v5 driver in the YugabyteDB source. It is thrown by results.Values() inside the row-scanning loop of RunSQL, meaning the query itself started successfully but one specific row could not be decoded into Go values. It is a data-extraction failure, not a query-execution failure (that is handled separately by results.Err()).

Source

Thrown at internal/sources/yugabytedb/yugabytedb.go:119

}

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

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

	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)
		}
		vMap := make(map[string]any)
		for i, f := range fields {
			val := sources.NormalizeValue(v[i], f.DataTypeOID)
			vMap[f.Name] = val
		}
		out = append(out, vMap)
	}

	// 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 initYugabyteDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, loadBalance, topologyKeys, refreshInterval, explicitFallback, failedHostTTL string) (*pgxpool.Pool, error) {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Inspect the wrapped error (%w) to identify the offending column or connection problem; fix the underlying cause it reports.
  2. Restrict SELECT to columns with types pgx can decode, or cast unsupported columns in SQL (e.g., CAST(col AS text)).
  3. Check network stability between the toolbox and the YugabyteDB node; retry the query if it was a transient connection drop.
  4. Verify driver/pgx and YugabyteDB versions are compatible; upgrade dependencies if a decoding bug was fixed upstream.
  5. Enable pgx logging (QueryTracer/Logger) for the exact failing statement and row.

Example fix

// before
rows, err := pool.Query(ctx, "SELECT * FROM my_table")
// after
rows, err := pool.Query(ctx, "SELECT id, name, payload::text AS payload FROM my_table")
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer explicit columns and cast unsupported types in SQL before invoking the tool
// SELECT id, name, payload::text AS payload FROM my_table;

Try / catch

try {
  const rows = await callTool("execute_sql", { sql: "SELECT ..." });
} catch (e) {
  if (String(e.message).includes("unable to parse row")) {
    // inspect wrapped cause, narrow selected columns / cast types, retry
  }
}

Prevention

When it happens

Trigger: Calling RunSQL (or the yugabytedb execute_sql tool) and pgx fails to decode a row's values via Rows.Values() — typically when a column contains a type value that cannot be materialized at that point in iteration, or when the connection breaks mid-row fetch.

Common situations: Queries returning exotic or custom column types that pgx cannot decode, broken/terminated connections while streaming large result sets, driver/database version mismatches (e.g., YugabyteBCS/pgx protocol incompatibilities), or OOM/interruption while fetching rows.

Understand the failure class

Related errors


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