{"record":{"id":"063f95c1178e4c50","repo":"gastownhall/beads","slug":"db-listremotes-rows-w","errorCode":null,"errorMessage":"db: ListRemotes: rows: %w","messagePattern":"db: ListRemotes: rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/remote.go","lineNumber":54,"sourceCode":"}\n\nfunc (r *remoteSQLRepositoryImpl) ListRemotes(ctx context.Context) ([]domain.Remote, error) {\n\trows, err := r.runner.QueryContext(ctx, \"SELECT name, url FROM dolt_remotes\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"db: ListRemotes: query: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar remotes []domain.Remote\n\tfor rows.Next() {\n\t\tvar rem domain.Remote\n\t\tif err := rows.Scan(&rem.Name, &rem.URL); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"db: ListRemotes: scan: %w\", err)\n\t\t}\n\t\tremotes = append(remotes, rem)\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"db: ListRemotes: rows: %w\", err)\n\t}\n\treturn remotes, nil\n}\n","sourceCodeStart":36,"sourceCodeEnd":58,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/remote.go#L36-L58","documentation":"This error is returned by ListRemotes after iterating rows, when rows.Err() reports an error encountered during iteration (e.g. the connection dropped or the query was aborted mid-result-set). The scan of earlier rows succeeded, but the full result was not retrieved.","triggerScenarios":"Calling ListRemotes when the database connection fails or the context is cancelled while streaming rows from the dolt_remotes query — any driver-level error surfaced only via rows.Err() after Next() returns false.","commonSituations":"Long-lived result set interrupted by network blip to the SQL server; context timeout expiring while listing many remotes; Dolt server killed mid-query.","solutions":["Read the wrapped cause after 'rows:' for the driver error","Retry ListRemotes with a fresh context if the cause is transient (connection reset, deadline exceeded)","Increase the context timeout when listing against a slow/remote SQL server","Check server logs for aborted connections around the failure time"],"exampleFix":"// before\nctx := context.Background()\nremotes, err := store.ListRemotes(ctx)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\ndefer cancel()\nremotes, err := store.ListRemotes(ctx)\nif err != nil && isTransient(err) { remotes, err = store.ListRemotes(ctx) }","handlingStrategy":"retry","validationCode":"ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)\ndefer cancel() // generous timeout avoids mid-iteration aborts","typeGuard":"func isRowsErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"ListRemotes: rows:\")\n}","tryCatchPattern":"var remotes []domain.Remote\nvar err error\nfor i := 0; i < 3; i++ {\n    remotes, err = store.ListRemotes(ctx)\n    if err == nil || !isTransient(err) { break }\n    time.Sleep(backoff(i))\n}","preventionTips":["Use contexts with adequate timeouts for remote listing","Retry transient connection errors with backoff","Monitor SQL server stability; investigate aborted connections"],"tags":["database","sql","dolt","rows-iteration"],"backgroundTag":"sql-rows-iteration-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}