googleapis/mcp-toolbox · error
unable to iterate through query results: %w
Error message
unable to iterate through query results: %w
What it means
This error wraps any failure returned by the BigQuery row iterator's Next() call while paging through a query's result rows. The library throws it because a successful query job can still fail during row streaming — the initial job completion does not guarantee every page of rows can be fetched. The original iterator error (including context.DeadlineExceeded, transport failures, or page-level BigQuery API errors) is preserved via %w so callers can inspect it with errors.Is/errors.As.
Source
Thrown at internal/sources/bigquery/bigquery.go:643
// column names to values, and return the collection of rows.
job, err := query.Run(ctx)
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)
}
it, err := job.Read(ctx)
if err != nil {
return nil, fmt.Errorf("unable to read query results: %w", err)
}
out := []any{}
for s.MaxQueryResultRows <= 0 || len(out) < s.MaxQueryResultRows {
var val []bigqueryapi.Value
err = it.Next(&val)
if err == iterator.Done {
break
}
if err != nil {
return nil, fmt.Errorf("unable to iterate through query results: %w", err)
}
schema := it.Schema
row := orderedmap.Row{}
for i, field := range schema {
row.Add(field.Name, NormalizeValue(val[i]))
}
out = append(out, row)
}
// If the query returned any rows, return them directly.
if len(out) > 0 {
return out, nil
}
// This handles the standard case for a SELECT query that successfully
// executes but returns zero rows.
if statementType == "SELECT" {
return "The query returned 0 rows.", nil
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Retry the operation (the query itself, not just the iteration) if the wrapped error is transient (net errors, 5xx, 429) — BigQuery iterators are not resumable mid-stream.
- Increase the request's context deadline / timeout so slow result streams can complete.
- Check the wrapped error with errors.As to see if it's a googleapi.Error and inspect its code for quota or permission issues.
- Reduce result size (LIMIT, paging) to shorten the streaming window and lower the chance of mid-iteration failures.
Example fix
// before
for {
var val []bigqueryapi.Value
err = it.Next(&val)
if err == iterator.Done { break }
if err != nil { return nil, fmt.Errorf("unable to iterate through query results: %w", err) }
}
// after
for {
var val []bigqueryapi.Value
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()
itPager.PageInfo().MaxSize = 10000 // fetch larger pages, fewer round-trips
err = it.Next(&val)
if errors.Is(err, iterator.Done) { break }
if err != nil {
if isRetryable(err) { /* retry query */ }
return nil, fmt.Errorf("unable to iterate through query results: %w", err)
}
} Defensive patterns
Strategy: try-catch
Try / catch
// Go
rows, err := tool.Invoke(ctx, params)
if err != nil {
if strings.Contains(err.Error(), "unable to iterate through query results") {
var gerr *googleapi.Error
if errors.As(err, &gerr) && (gerr.Code == 429 || gerr.Code >= 500) {
// retry the whole query after backoff; iterators are not resumable
}
if errors.Is(err, context.DeadlineExceeded) {
// re-invoke with a longer deadline
}
}
} Prevention
- Set generous context timeouts for queries expected to return many rows.
- Use LIMIT/pagination to keep result streams short.
- Retry the entire query on transient (5xx/429) failures instead of resuming iteration.
- Monitor for rate-limit errors and add backoff.
When it happens
Trigger: Calling Invoke on a BigQuery tool whose query returns rows, and it.Next(&val) (bigquery.RowIterator.Next) returns a non-nil error other than iterator.Done — e.g. a transient HTTP/transport failure while fetching the next page, a context deadline exceeded mid-iteration, or a page-level BigQuery API error (5xx, rate limit) while reading results.
Common situations: Long-running queries streamed over a slow network; context timeouts during result pagination; BigQuery backend transient errors or 429 rate-limit responses on the tabledata/list pages; stopped or expired jobs; cancelled requests when the caller's context times out.
Related errors
- failed to verify allowedDataset '%s' in project '%s': %w
- failed to create BigQuery client for project %q: %w
- failed to create BigQuery v2 service: %w
- failed to list data scans: %w
- failed to list data products: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/f6af9e355ac6e290.
Report an issue: GitHub.