gastownhall/beads · error
get dependency records: rows: %w
Error message
get dependency records: rows: %w
What it means
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.
Source
Thrown at internal/storage/issueops/dependency_queries.go:132
}
rows, err := tx.QueryContext(ctx, fmt.Sprintf(
`SELECT issue_id, %s AS depends_on_id, type, created_at, created_by, metadata, thread_id
FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, depends_on_id, type, id`,
DepTargetExpr, depTable, strings.Join(placeholders, ",")), args...)
if err != nil {
return fmt.Errorf("get dependency records from %s: %w", depTable, err)
}
for rows.Next() {
dep, scanErr := scanDependencyRow(rows)
if scanErr != nil {
_ = rows.Close()
return fmt.Errorf("get dependency records: scan: %w", scanErr)
}
result[dep.IssueID] = append(result[dep.IssueID], dep)
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return fmt.Errorf("get dependency records: rows: %w", err)
}
}
return nil
}
// GetDependentRecordsForIssuesInTx returns raw dependency rows keyed by TARGET
// id: for each id in targetIDs, the rows whose target is that id — its INCOMING
// edges, i.e. its dependents — spanning BOTH the durable and wisp dependency
// tables and applying NO type filter or visibility policy (the caller filters
// at hydration). It is the batched, target-keyed mirror of the source-keyed
// GetDependencyRecordsForIssuesInTx: one query per table per batch of
// queryBatchSize target ids, so cost is O(1 + N/queryBatchSize) round-trips per
// table rather than O(N) — the whole-page read that lets a caller render every
// id's inbound `blocks` edges without a per-id fan-out.
//
// A target is matched by the coalesced target expression (DepTargetExpr) — the
// same predicate the batched source-keyed blocks/counts reads use — so an id
// that appears in any of the three typed target columns resolves; each returnedView on GitHub (pinned to 71377f2769)
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.
Defensive patterns
Strategy: retry
Try / catch
recs, err := GetDependencyRecordsForIssuesInTx(ctx, tx, ids)
if err != nil {
if strings.Contains(err.Error(), "get dependency records: rows:") && isTransient(err) {
return retryWithBackoff(ctx, func() error {
recs, err = GetDependencyRecordsForIssuesInTx(ctx, tx, ids)
return err
})
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- row iteration error: %w
- iterate inbound dependencies from %s: %w
- final cycle check failed (no edges added): %w
- get dependency counts: blocker rows: %w
- get dependency counts: dependent rows: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/598cf6f9d246a50b.
Report an issue: GitHub.