gastownhall/beads · error
dependency graph: rows %s: %w
Error message
dependency graph: rows %s: %w
What it means
After iterating a dependency table's rows, appendDependencyGraphInTx checks rows.Err() and wraps any deferred iteration error as 'dependency graph: rows <table>: %w'. This catches driver-level failures that surface mid-iteration (connection drop, query abort) rather than at query or scan time.
Source
Thrown at internal/storage/issueops/cycles.go:117
FROM %s
`, DepTargetExpr, depTable))
if err != nil {
return fmt.Errorf("dependency graph: query %s: %w", depTable, err)
}
for rows.Next() {
var issueID, dependsOnID, depType string
if err := rows.Scan(&issueID, &dependsOnID, &depType); err != nil {
_ = rows.Close()
return fmt.Errorf("dependency graph: scan %s: %w", depTable, err)
}
t := types.DependencyType(depType)
if t == types.DepBlocks || t == types.DepConditionalBlocks || (includeParentChild && t == types.DepParentChild) {
graph[issueID] = append(graph[issueID], dependsOnID)
}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return fmt.Errorf("dependency graph: rows %s: %w", depTable, err)
}
}
return nil
}
// CycleThroughEdgesInGraph reports a rendered cycle that traverses
// one of the new edges (issueID -> dependsOnID pairs), or "" when no new edge
// lies on a cycle. An edge u -> v is on a cycle exactly when u is reachable
// from v, so this is precise where cycle enumeration is not: a DFS-based
// detector records one cycle per back edge and can report a pre-existing
// cycle through the same nodes instead of the one the new edge created
// (bd-578h9.9). The graph must already contain the new edges.
func CycleThroughEdgesInGraph(graph map[string][]string, edges [][2]string) string {
for _, edge := range edges {
source, target := edge[0], edge[1]
if source == "" || target == "" {
continue
}View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error for transport/timeout causes and retry the operation
- Reduce graph size or batch the check to shorten row streaming
- Ensure a stable DB connection (timeouts, keepalives) for remote backends
Example fix
// before
// treat nil error after loop as success only
// after
if err := rows.Err(); err != nil { return fmt.Errorf("...: %w", err) } // already present; retry op on failure Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.HasPrefix(err.Error(), "dependency graph: rows ") {
cause := errors.Unwrap(err)
// transient network/backend error: backoff and retry the whole operation
return err
} Prevention
- Use stable, low-latency connections to the DB for graph checks
- Set generous query timeouts for large dependency tables
- Chunk cycle detection for very large graphs
When it happens
Trigger: The rows iterator encounters a transport/backend error while streaming rows of a dependency table during graph assembly — network drop to the DB, server abort, timeout.
Common situations: Large graphs over flaky/remote Dolt connections; query timeouts on very wide dependency tables; server restart mid-scan.
Related errors
- db: RawSQL Query: rows: %w
- iterate dependents for batch from %s: %w
- dolt server connection failed: %w
- failed to iterate peers for migration: %w
- db: ChildCounterSQLRepository.NextChildID: rows: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6593a3e6ea8869e5.
Report an issue: GitHub.