{"record":{"id":"713d1c1bc2b2b8e9","repo":"googleapis/mcp-toolbox","slug":"errors-encountered-during-row-iteration-w-713d1c","errorCode":null,"errorMessage":"errors encountered during row iteration: %w","messagePattern":"errors encountered during row iteration: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/tidb/tidb.go","lineNumber":180,"sourceCode":"\t\t\t\tif err := json.Unmarshal(byteVal, &unmarshaledData); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"unable to unmarshal json data %s\", val)\n\t\t\t\t}\n\t\t\t\tvMap[name] = unmarshaledData\n\t\t\tcase \"TEXT\", \"VARCHAR\", \"NVARCHAR\":\n\t\t\t\tbyteVal, ok := val.([]byte)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"expected []byte for text-like column, but got %T\", val)\n\t\t\t\t}\n\t\t\t\tvMap[name] = string(byteVal)\n\t\t\tdefault:\n\t\t\t\tvMap[name] = val\n\t\t\t}\n\t\t}\n\t\tout = append(out, vMap)\n\t}\n\n\tif err := results.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"errors encountered during row iteration: %w\", err)\n\t}\n\n\treturn out, nil\n}\n\nfunc IsTiDBCloudHost(host string) bool {\n\tpattern := `gateway\\d{2}\\.(.+)\\.(prod|dev|staging)\\.(.+)\\.tidbcloud\\.com`\n\tmatch, err := regexp.MatchString(pattern, host)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn match\n}\n\nfunc initTiDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname string, useSSL bool) (*sql.DB, error) {\n\t//nolint:all // Reassigned ctx\n\tctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)\n\tdefer span.End()","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/tidb/tidb.go#L162-L198","documentation":"TiDB RunSQL wraps any error returned by the *sql.Rows cursor after iterating all rows (results.Err()). During iteration the driver may hit network drops, context cancellation, or protocol errors that only surface via Err() once rows are exhausted. The toolbox wraps it so the underlying driver error is preserved via %w.","triggerScenarios":"Calling Source.RunSQL on a TiDB source where the underlying mysql driver connection breaks mid-result-set: network interruption, server-side query kill/timeout, context cancellation, or packet corruption while streaming rows.","commonSituations":"Long-running SELECTs on TiDB Cloud hitting query timeouts; idle connection dropped by a proxy/load balancer between rows; client context cancelled while a large result set is still streaming.","solutions":["Check the wrapped driver error for context cancellation/deadline and retry with a longer context timeout","Verify network stability between the client and TiDB (proxies, LBs, VPC peering) and connection max-lifetime settings","Reduce result set size (LIMIT, pagination) or raise TiDB query memory/timeout limits","Confirm TLS/connectivity to TiDB Cloud (port 4000, correct host) and driver version"],"exampleFix":"// before\nresults, err := pool.QueryContext(ctx, statement, params...)\n// after\nctx, cancel := context.WithTimeout(ctx, 5*time.Minute)\ndefer cancel()\nresults, err := pool.QueryContext(ctx, statement, params...)","handlingStrategy":"retry","validationCode":"// ensure context has enough headroom before running\nif deadline, ok := ctx.Deadline(); !ok || time.Until(deadline) < 30*time.Second {\n    var cancel context.CancelFunc\n    ctx, cancel = context.WithTimeout(ctx, 5*time.Minute)\n    defer cancel()\n}","typeGuard":null,"tryCatchPattern":"out, err := src.RunSQL(ctx, stmt, params)\nif err != nil && strings.Contains(err.Error(), \"errors encountered during row iteration\") {\n    if errors.Is(err, context.DeadlineExceeded) || isTransientNetErr(err) {\n        out, err = retryWithBackoff(3, func() (any, error) { return src.RunSQL(ctx, stmt, params) })\n    }\n}","preventionTips":["Always pass a context with an explicit, generous deadline for large result sets","Paginate large queries instead of streaming everything in one call","Set pool ConnMaxLifetime below any proxy/LB idle timeout","Monitor TiDB query kill events and timeout settings"],"tags":["database","tidb","row-iteration","query-execution"],"backgroundTag":"rows-iteration-error","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}