googleapis/mcp-toolbox · error

unable to parse rows: %w

Error message

unable to parse rows: %w

What it means

RunSQL executes a CQL statement via gocql Query.Iter; when iter.Close() returns an error, it means the iteration/consumption of the result set failed (including server-side errors surfaced at the end of iteration), wrapped as 'unable to parse rows'.

Source

Thrown at internal/sources/cassandra/cassandra.go:118

func (s *Source) RunSQL(ctx context.Context, statement string, params parameters.ParamValues) (any, error) {
	sliceParams := params.AsSlice()
	iter := s.CassandraSession().Query(statement, sliceParams...).IterContext(ctx)

	// Create a slice to store the out
	var out []map[string]interface{}

	// Scan results into a map and append to the slice
	for {
		row := make(map[string]interface{}) // Create a new map for each row
		if !iter.MapScan(row) {
			break // No more rows
		}
		out = append(out, row)
	}

	if err := iter.Close(); err != nil {
		return nil, fmt.Errorf("unable to parse rows: %w", err)
	}
	return out, nil
}

var _ sources.Source = &Source{}

func initCassandraSession(ctx context.Context, tracer trace.Tracer, c Config) (*gocql.Session, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, c.Name)
	defer span.End()

	// Validate authentication configuration
	if c.Password != "" && c.Username == "" {
		return nil, fmt.Errorf("invalid Cassandra configuration: password provided without a username")
	}

	cluster := gocql.NewCluster(c.Hosts...)
	cluster.ProtoVersion = c.ProtoVersion

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the wrapped inner error for the actual CQL/server failure.
  2. Retry the statement if it was a transient timeout or node error.
  3. Fix the CQL statement if it is invalid for the schema.
  4. Check cluster health; a coordinator may have died mid-query.
  5. Increase timeout/consistency settings in the cluster config if appropriate.

Example fix

// before
rows, err := src.RunSQL(ctx, "SELECT * FROM missing_table")
// after
rows, err := src.RunSQL(ctx, "SELECT * FROM existing_table")
Defensive patterns

Strategy: try-catch

Validate before calling

rows, err := src.RunSQL(ctx, stmt)
if err != nil { /* handle */ }

Try / catch

rows, err := src.RunSQL(ctx, stmt)
if err != nil {
    if strings.Contains(err.Error(), "timeout") { /* retry */ }
    return fmt.Errorf("runsql failed: %w", err)
}

Prevention

When it happens

Trigger: Calling RunSQL when the iterator fails while consuming rows or on final Close — e.g. query timeout, coordinator error, or malformed result.

Common situations: Query timeouts, node failures mid-scan, invalid query caught server-side, consistency errors 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/205e5a10aabcbd64. Report an issue: GitHub.