gastownhall/beads · error
dependency graph: query %s: %w
Error message
dependency graph: query %s: %w
What it means
appendDependencyGraphInTx failed querying a dependency table (per depTable in the given list) while assembling the blocking/scheduling dependency graph for cycle detection. The table name is interpolated into the message; the driver error is wrapped. This aborts the cycle-check, and the caller treats graph-build failure as fatal for the operation.
Source
Thrown at internal/storage/issueops/cycles.go:102
func AppendBlockingGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string) error {
return appendDependencyGraphInTx(ctx, tx, depTables, graph, false)
}
// AppendSchedulingGraphInTx adds blocks, conditional-blocks, and parent-child
// edges to graph for validating mutations against the combined scheduling
// graph. DetectCycles intentionally continues to use AppendBlockingGraphInTx.
func AppendSchedulingGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string) error {
return appendDependencyGraphInTx(ctx, tx, depTables, graph, true)
}
func appendDependencyGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string, includeParentChild bool) error {
for _, depTable := range depTables {
rows, err := tx.QueryContext(ctx, fmt.Sprintf(`
SELECT issue_id, %s AS depends_on_id, type
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 nilView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped driver error and the named table to find the storage-level cause
- Apply pending migrations so all dependency tables exist
- Retry the operation in a fresh transaction; reduce concurrent dependency writes during cycle checks
Example fix
// before
// retry blindly
// after
if strings.Contains(err.Error(), "no such table") { runMigrations(); retry() } Defensive patterns
Strategy: retry
Try / catch
if err := AddDependency(ctx, ...); err != nil {
if strings.HasPrefix(err.Error(), "dependency graph: query ") {
// backoff and retry the operation in a new transaction
}
return err
} Prevention
- Keep schema migrations current
- Avoid heavy concurrent dependency mutations
- Use bounded retries with backoff on cycle-check operations
When it happens
Trigger: QueryContext over a dependency table fails during AppendBlockingGraphInTx / AppendSchedulingGraphInTx — missing table, locked DB, connection loss mid-cycle-check.
Common situations: Schema drift (dependency table absent after partial migration); storage contention while another transaction mutates dependencies; transient driver failures on large graphs.
Related errors
- ErrQuery
- failed to get federation peer: %w
- failed to list federation peers: %w
- failed to get comments: %w
- failed to check issue_counter for prefix %q: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cfcad95c1fd3bb9a.
Report an issue: GitHub.