{"record":{"id":"0b6d664285528226","repo":"gastownhall/beads","slug":"count-edges-in-s-rows-w","errorCode":null,"errorMessage":"count edges in %s: rows: %w","messagePattern":"count edges in (.+?): rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/edge_counts.go","lineNumber":164,"sourceCode":"\t\t\trows, err := tx.QueryContext(ctx, query, edgeCountArgs(batch, request)...)\n\t\t\tif err != nil {\n\t\t\t\tif optionalBlockedTable(plane.dependencies) && isTableNotExistError(err) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"count edges in %s: %w\", plane.dependencies, err)\n\t\t\t}\n\t\t\tfor rows.Next() {\n\t\t\t\tvar id string\n\t\t\t\tvar n int64\n\t\t\t\tif scanErr := rows.Scan(&id, &n); scanErr != nil {\n\t\t\t\t\t_ = rows.Close()\n\t\t\t\t\treturn nil, fmt.Errorf(\"count edges in %s: scan: %w\", plane.dependencies, scanErr)\n\t\t\t\t}\n\t\t\t\ttallies[id] += n\n\t\t\t}\n\t\t\t_ = rows.Close()\n\t\t\tif err := rows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"count edges in %s: rows: %w\", plane.dependencies, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn tallies, nil\n}\n\n// buildEdgeCountQuery returns the grouped count for one dependency plane, keyed\n// by the anchor end the request's direction names.\n//\n// THE TARGET END IS ALWAYS THE COALESCE EXPRESSION, never the STORED generated\n// `depends_on_id` column. Both dependency tables define that column as\n// GENERATED ALWAYS AS the same COALESCE, and inside an aggregate the pure-Go\n// GMS analyzer can prune the base columns it derives from and then fail with\n// \"column depends_on_id could not be found in any table in scope\"\n// (dolt/counts.go says so at depTargetExpr). Every other aggregate over these\n// tables in this package resolves the target the same way.\nfunc buildEdgeCountQuery(depTable, sourceTable string, batchSize int, request publicops.EdgeCountRequest) string {\n\tplaceholders := strings.TrimSuffix(strings.Repeat(\"?,\", batchSize), \",\")","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/edge_counts.go#L146-L182","documentation":"After consuming all rows of the edge-count query, rows.Err() returned a non-nil error, meaning the result set was interrupted mid-iteration (connection loss, cancellation, driver I/O error) rather than ending normally. The table name is included to locate the failing plane.","triggerScenarios":"Network drop or server restart while streaming rows of a large edge-count batch; ctx cancellation during iteration; driver-level read timeouts on big result sets.","commonSituations":"Counting edges for thousands of anchors where iteration outlasts the connection lifetime; a proxy/firewall idle timeout killing the connection; context deadlines in CLI commands cancelled by the user or a supervisor.","solutions":["Retry the count; the error is usually transient (connection/cancellation).","Increase query/connection timeouts or batch size tuning so iteration completes within limits.","Check context deadlines upstream and give the operation a longer budget.","Inspect the wrapped error (rows.Err chain) for driver-specific codes like bad connection and enable driver auto-reconnect where appropriate."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := ExecuteEdgeCount(ctx, tx, req)\nif err != nil && strings.Contains(err.Error(), \": rows: \") {\n\t// typically transient: retry with backoff and a fresh transaction\n\tres, err = retryWithBackoff(func() (publicops.EdgeCountResult, error) { return ExecuteEdgeCount(ctx, tx, req) })\n}","preventionTips":["Give large counts a generous context deadline","Retry with backoff on rows-iteration errors","Avoid proxies/idle timeouts shorter than the query duration","Reopen the transaction on retry rather than reusing a possibly dead tx"],"tags":["database","sql","rows-iteration","connection"],"backgroundTag":"sql-rows-iteration-error","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}