{"record":{"id":"009b55713bf4cb73","repo":"googleapis/mcp-toolbox","slug":"error-iterating-rows-w-009b55","errorCode":null,"errorMessage":"error iterating rows: %w","messagePattern":"error iterating rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/sqlite/sqlite.go","lineNumber":158,"sourceCode":"\t\t\t\trow.Add(name, nil)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Handle JSON data\n\t\t\tif jsonString, ok := val.(string); ok {\n\t\t\t\tvar unmarshaledData any\n\t\t\t\tif json.Unmarshal([]byte(jsonString), &unmarshaledData) == nil {\n\t\t\t\t\trow.Add(name, unmarshaledData)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Store the value in the map\n\t\t\trow.Add(name, val)\n\t\t}\n\t\tout = append(out, row)\n\t}\n\n\tif err = rows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"error iterating rows: %w\", err)\n\t}\n\n\treturn out, nil\n}\n\nfunc initSQLiteConnection(ctx context.Context, tracer trace.Tracer, name, dbPath string) (*sql.DB, error) {\n\t//nolint:all // Reassigned ctx\n\tctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)\n\tdefer span.End()\n\n\t// Open database connection\n\tdb, err := sql.Open(\"sqlite\", dbPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"sql.Open: %w\", err)\n\t}\n\n\t// Set some reasonable defaults for SQLite\n\tdb.SetMaxOpenConns(1) // SQLite only supports one writer at a time","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/sqlite/sqlite.go#L140-L176","documentation":"sqlite RunSQL (internal/sources/sqlite/sqlite.go:158) checks rows.Err() after the iteration loop completes. A non-nil error means the row iteration itself failed partway (driver/connection error mid-stream), not that all rows were read successfully. The error is wrapped as \"error iterating rows\" and returned instead of the partial results.","triggerScenarios":"RunSQL where rows.Err() is non-nil after the for rows.Next() loop: an I/O error reading from the database file mid-iteration, out-of-memory in the driver, or context cancellation while fetching rows.","commonSituations":"Database file removed or corrupted while a query streams; disk I/O errors; very large result sets hitting memory limits; context deadline expiring during iteration.","solutions":["Read the wrapped driver error to identify the underlying I/O or OOM condition","Reduce result set size with LIMIT or tighter WHERE clauses","Extend the context timeout if deadlines fire during large scans","Verify database file integrity and disk health (PRAGMA integrity_check, dmesg for I/O errors)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := source.RunSQL(ctx, stmt, params)\nif err != nil && strings.Contains(err.Error(), \"error iterating rows\") {\n\t// fail fast, alert on disk/IO health, optionally retry with LIMIT-reduced query\n\treturn fmt.Errorf(\"sqlite iteration failed: %w\", err)\n}","preventionTips":["Bound result sizes with LIMIT in tool SQL","Monitor disk health and free space on the sqlite host","Set adequate context timeouts for large scans"],"tags":["sqlite","rows-iteration","io"],"backgroundTag":"row-iteration-failed","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"}