{"record":{"id":"598cf6f9d246a50b","repo":"gastownhall/beads","slug":"get-dependency-records-rows-w","errorCode":null,"errorMessage":"get dependency records: rows: %w","messagePattern":"get dependency records: rows: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":132,"sourceCode":"\t\t}\n\t\trows, err := tx.QueryContext(ctx, fmt.Sprintf(\n\t\t\t`SELECT issue_id, %s AS depends_on_id, type, created_at, created_by, metadata, thread_id\n\t\t\t FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, depends_on_id, type, id`,\n\t\t\tDepTargetExpr, depTable, strings.Join(placeholders, \",\")), args...)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get dependency records from %s: %w\", depTable, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tdep, scanErr := scanDependencyRow(rows)\n\t\t\tif scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"get dependency records: scan: %w\", scanErr)\n\t\t\t}\n\t\t\tresult[dep.IssueID] = append(result[dep.IssueID], dep)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"get dependency records: rows: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// GetDependentRecordsForIssuesInTx returns raw dependency rows keyed by TARGET\n// id: for each id in targetIDs, the rows whose target is that id — its INCOMING\n// edges, i.e. its dependents — spanning BOTH the durable and wisp dependency\n// tables and applying NO type filter or visibility policy (the caller filters\n// at hydration). It is the batched, target-keyed mirror of the source-keyed\n// GetDependencyRecordsForIssuesInTx: one query per table per batch of\n// queryBatchSize target ids, so cost is O(1 + N/queryBatchSize) round-trips per\n// table rather than O(N) — the whole-page read that lets a caller render every\n// id's inbound `blocks` edges without a per-id fan-out.\n//\n// A target is matched by the coalesced target expression (DepTargetExpr) — the\n// same predicate the batched source-keyed blocks/counts reads use — so an id\n// that appears in any of the three typed target columns resolves; each returned","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L114-L150","documentation":"After iterating rows in getDependencyRecordsIntoFromTable, rows.Err() reported a streaming failure, wrapped as 'get dependency records: rows: %w'. The result set broke partway through (connection drop, server abort), so the accumulated per-issue dependency map may be incomplete and the whole call fails. This is the per-ID-list analogue of the full-table rows iteration error.","triggerScenarios":"rows.Err() non-nil after the row loop in GetDependencyRecordsForIssuesInTx / GetDependencyRecordsForIssuesFromTableInTx — network interruption or driver read failure while streaming rows for the requested issue IDs.","commonSituations":"Unstable connection to a remote Dolt server during a multi-table fan-out query; server-side query timeout on large ID batches; aggressive idle timeouts killing the connection mid-result.","solutions":["Retry in a fresh transaction; the read is idempotent and the partial map is discarded.","Unwrap the %w cause for timeout/network specifics and tune connection timeouts/keepalives.","Reduce batch size for the ID list so each streamed result completes before timeouts hit."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"recs, err := GetDependencyRecordsForIssuesInTx(ctx, tx, ids)\nif err != nil {\n    if strings.Contains(err.Error(), \"get dependency records: rows:\") && isTransient(err) {\n        return retryWithBackoff(ctx, func() error {\n            recs, err = GetDependencyRecordsForIssuesInTx(ctx, tx, ids)\n            return err\n        })\n    }\n    return err\n}","preventionTips":["Keep ID batches small so each streamed result completes before timeouts.","Use keepalives/timeout tuning on the database connection.","Treat rows-iteration failures as transient and retry in a fresh transaction.","Avoid issuing many large fan-out queries concurrently over one unstable connection."],"tags":["go","database","network","row-iteration","transient"],"backgroundTag":"row-iteration-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}