googleapis/mcp-toolbox · error

unable to parse row: %w

Error message

unable to parse row: %w

What it means

Returned by the cloud-sql-mssql source's RunSQL when results.Scan(values...) fails while reading a row from an executed query. Scan converts driver values into []any destinations; it fails on driver errors, type conversion issues, or NULL handling problems during row materialization. This is a row-level data error, not a query failure.

Source

Thrown at internal/sources/cloudsqlmssql/cloud_sql_mssql.go:138

	defer results.Close()

	cols, err := results.Columns()
	// If Columns() errors, it might be a DDL/DML without an OUTPUT clause.
	// We proceed, and results.Err() will catch actual query execution errors.
	// 'out' will remain an empty slice if cols is empty or err is not nil here.
	out := []any{}
	if err == nil && len(cols) > 0 {
		// 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]
		}

		for results.Next() {
			scanErr := results.Scan(values...)
			if scanErr != nil {
				return nil, fmt.Errorf("unable to parse row: %w", scanErr)
			}
			row := orderedmap.Row{}
			for i, name := range cols {
				row.Add(name, rawValues[i])
			}
			out = append(out, row)
		}
	}

	// Check for errors from iterating over rows or from the query execution itself.
	// results.Close() is handled by defer.
	if err := results.Err(); err != nil {
		return nil, fmt.Errorf("errors encountered during query execution or row processing: %w", err)
	}

	return out, nil
}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Check the wrapped scanErr for the specific column/type causing the failure
  2. Exclude or CAST problematic columns in the query (e.g. CAST(col AS NVARCHAR(MAX)))
  3. Upgrade cloud.google.com/go/cloudsqlconn and the sqlserver driver to the latest version
  4. Retry if the error indicates a transient network failure mid-stream

Example fix

// before
SELECT id, location FROM places; -- location is geometry
// after
SELECT id, CAST(location AS NVARCHAR(MAX)) AS location FROM places;
Defensive patterns

Strategy: try-catch

Try / catch

out, err := src.RunSQL(ctx, statement, params)
if err != nil {
    var scanErr *ScanError // conceptually identify scan failures by message
    if strings.Contains(err.Error(), "unable to parse row") {
        // retry with problematic columns CAST to safe types
        return fmt.Errorf("row decode failed; consider CASTing exotic columns: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: QueryContext succeeded and rows are being iterated, but results.Scan errors on a particular row — typically an underlying driver/network failure mid-result-stream, or a value the driver cannot decode into an interface{} destination (e.g. corrupted or unusual column data types like unsupported CLR/geometry types).

Common situations: Selecting exotic SQL Server column types (hierarchyid, geometry, geography) the driver can't scan, connection dropped mid-stream on large result sets, TEXT/NTEXT with invalid encodings, driver version bugs with specific types.

Understand the failure class

Related errors


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