googleapis/mcp-toolbox · error

errors encountered during row iteration: %w

Error message

errors encountered during row iteration: %w

What it means

RunSQL wraps results.Err() with this message after the row loop. results.Err() reports any error encountered during iteration that was not surfaced by Scan — most often the connection or result stream failed partway through reading rows, so the result set is incomplete and cannot be trusted.

Source

Thrown at internal/sources/singlestore/singlestore.go:162

		}
		vMap := make(map[string]any)
		for i, name := range cols {
			val := rawValues[i]
			if val == nil {
				vMap[name] = nil
				continue
			}

			vMap[name], err = mysqlcommon.ConvertToType(colTypes[i], val)
			if err != nil {
				return nil, fmt.Errorf("errors encountered when converting values: %w", err)
			}
		}
		out = append(out, vMap)
	}

	if err := results.Err(); err != nil {
		return nil, fmt.Errorf("errors encountered during row iteration: %w", err)
	}

	return out, nil
}

func initSingleStoreConnectionPool(ctx context.Context, tracer trace.Tracer, cfg Config) (*sql.DB, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, cfg.Name)
	defer span.End()

	// Build query parameters via url.Values for deterministic order and proper escaping.
	connectionParams := url.Values{}

	mysqlCfg := mysql.Config{
		User:                 cfg.User,
		Passwd:               cfg.Password,
		Net:                  "tcp",
		Addr:                 fmt.Sprintf("%s:%s", cfg.Host, cfg.Port),

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Retry with a smaller result set (add LIMIT / pagination) to see if large streaming is the trigger.
  2. Increase queryTimeout so the derived readTimeout accommodates the full result stream.
  3. Check the wrapped driver error and SingleStore node logs for connection aborts.
  4. Tune network intermediaries (LB idle timeouts) for long-running queries.
  5. Enable TCP keepalives in connectionParams to keep idle streaming connections alive.

Example fix

// before
{"statement": "SELECT * FROM huge_table"}
// after
{"statement": "SELECT * FROM huge_table LIMIT 1000"}
Defensive patterns

Strategy: retry

Validate before calling

// Prefer bounded queries for large tables
// validation: check estimated size first
// SELECT COUNT(*) FROM huge_table;  -- then add LIMIT if large

Try / catch

out, err := source.RunSQL(ctx, stmt, params)
if err != nil && strings.Contains(err.Error(), "errors encountered during row iteration") {
    // stream aborted: retry with LIMIT/pagination
    out, err = source.RunSQL(ctx, stmt+" LIMIT 1000", params)
}

Prevention

When it happens

Trigger: The result set iteration (results.Next()) terminated abnormally due to a lost connection, server abort, or read timeout after some rows were already processed.

Common situations: Very large result sets exceeding readTimeout, proxies/firewalls dropping long-lived connections mid-stream, server restarting during a query, or OOM kills on the SingleStore node for huge queries.

Related errors


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