gastownhall/beads · error
db: DependencySQLRepository.GetBlockingInfo: outbound: %w
Error message
db: DependencySQLRepository.GetBlockingInfo: outbound: %w
What it means
Wraps a failure from the outbound scanBlockingRows query in GetBlockingInfo, which selects outgoing 'blocks' and 'parent-child' edges for the given issues. The BlockingInfo result (Blocks/BlockedBy/Parent maps) cannot be built, so the caller gets an empty struct and this error.
Source
Thrown at internal/storage/domain/db/dependency.go:502
BlockedBy: make(map[string][]string),
Blocks: make(map[string][]string),
Parent: make(map[string]string),
}
if len(issueIDs) == 0 {
return info, nil
}
table := pickDepTable(opts.UseWispsTable)
idPlaceholders, idArgs := buildInPlaceholders(issueIDs)
//nolint:gosec // G201: table and depTargetExpr are hardcoded constants
outQ := fmt.Sprintf(
"SELECT issue_id, %s AS depends_on_id, type FROM %s WHERE issue_id IN (%s) AND type IN ('blocks', 'parent-child')",
depTargetExpr, table, idPlaceholders,
)
outRows, err := r.scanBlockingRows(ctx, outQ, idArgs)
if err != nil {
return domain.BlockingInfo{}, fmt.Errorf("db: DependencySQLRepository.GetBlockingInfo: outbound: %w", err)
}
//nolint:gosec // G201: table and depTargetExpr are hardcoded constants
inQ := fmt.Sprintf(
"SELECT issue_id, %s AS depends_on_id, type FROM %s WHERE %s IN (%s) AND type = 'blocks'",
depTargetExpr, table, depTargetExpr, idPlaceholders,
)
inRows, err := r.scanBlockingRows(ctx, inQ, idArgs)
if err != nil {
return domain.BlockingInfo{}, fmt.Errorf("db: DependencySQLRepository.GetBlockingInfo: inbound: %w", err)
}
statusIDs := make(map[string]struct{})
for _, row := range outRows {
statusIDs[row.dependsOnID] = struct{}{}
}
for _, row := range inRows {
statusIDs[row.dependsOnID] = struct{}{}View on GitHub (pinned to 71377f2769)
Solutions
- Chunk issueIDs and merge the BlockingInfo results.
- Verify opts.UseWispsTable matches where the deps live.
- Retry on a fresh connection; read-only.
- Confirm dep table schema matches expectations after upgrades (scan errors).
Example fix
// before
info, err := deps.GetBlockingInfo(ctx, ids, domain.DepListOpts{UseWispsTable: false})
// after
info, err := deps.GetBlockingInfo(ctx, ids[:500], domain.DepListOpts{UseWispsTable: false})
if err != nil { return err }
info2, err := deps.GetBlockingInfo(ctx, ids[500:], domain.DepListOpts{UseWispsTable: false})
mergeBlockingInfo(info, info2) Defensive patterns
Strategy: validation
Validate before calling
if len(issueIDs) == 0 { return domain.BlockingInfo{}, nil }
if len(issueIDs) > 500 { /* chunk and merge BlockingInfo maps */ } Try / catch
if err != nil && strings.Contains(err.Error(), "GetBlockingInfo: outbound") {
// retry read-only or chunk IDs and merge Blocks/Parent maps
} Prevention
- Chunk ID lists for blocking-info panels rendering many issues.
- Set UseWispsTable to match the deps storage.
- Retry freely; queries are read-only.
- Re-run migrations if scan errors appear after an upgrade.
When it happens
Trigger: GetBlockingInfo(ctx, issueIDs, opts) with Direction-dependent outbound query failing: placeholder limit for many IDs, connection error, table mismatch (UseWispsTable), or scan error in scanBlockingRows.
Common situations: Rendering 'blocked by' panels for many issues; querying wisps with the wrong flag; long-running sessions whose connection was reaped by the server.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- db: DependencySQLRepository.GetBlockingInfo: inbound: %w
- ErrQuery
- failed to get federation peer: %w
- failed to list federation peers: %w
- failed to get comments: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/193cf954aa09ae2c.
Report an issue: GitHub.