gastownhall/beads · error
db: DependencySQLRepository.CountsByIssueIDs (out): %w
Error message
db: DependencySQLRepository.CountsByIssueIDs (out): %w
What it means
Wraps a failure from the outgoing 'blocks' count query in CountsByIssueIDs (SELECT issue_id, COUNT(*) ... type='blocks' GROUP BY issue_id) executed via scanCounts. The per-issue outgoing blocking count could not be fetched, so the counts map is not returned at all.
Source
Thrown at internal/storage/domain/db/dependency.go:467
func (r *dependencySQLRepositoryImpl) CountsByIssueIDs(ctx context.Context, issueIDs []string, opts domain.DepCountsOpts) (map[string]*types.DependencyCounts, error) {
result := make(map[string]*types.DependencyCounts)
if len(issueIDs) == 0 {
return result, nil
}
for _, id := range issueIDs {
result[id] = &types.DependencyCounts{}
}
idPlaceholders, idArgs := buildInPlaceholders(issueIDs)
table := pickDepTable(opts.UseWispsTable)
//nolint:gosec // G201: table is one of two hardcoded constants
outQ := fmt.Sprintf(
`SELECT issue_id, COUNT(*) FROM %s WHERE issue_id IN (%s) AND type = 'blocks' GROUP BY issue_id`,
table, idPlaceholders,
)
if err := scanCounts(ctx, r.runner, outQ, idArgs, result, func(c *types.DependencyCounts, n int) { c.DependencyCount = n }); err != nil {
return nil, fmt.Errorf("db: DependencySQLRepository.CountsByIssueIDs (out): %w", err)
}
//nolint:gosec // G201: table and depTargetExpr are hardcoded
inQ := fmt.Sprintf(
`SELECT %s AS depends_on_id, COUNT(*) FROM %s WHERE %s IN (%s) AND type = 'blocks' GROUP BY %s`,
depTargetExpr, table, depTargetExpr, idPlaceholders, depTargetExpr,
)
if err := scanCounts(ctx, r.runner, inQ, idArgs, result, func(c *types.DependencyCounts, n int) { c.DependentCount = n }); err != nil {
return nil, fmt.Errorf("db: DependencySQLRepository.CountsByIssueIDs (in): %w", err)
}
return result, nil
}
func (r *dependencySQLRepositoryImpl) GetBlockingInfo(ctx context.Context, issueIDs []string, opts domain.DepListOpts) (domain.BlockingInfo, error) {
info := domain.BlockingInfo{
BlockedBy: make(map[string][]string),
Blocks: make(map[string][]string),View on GitHub (pinned to 71377f2769)
Solutions
- Chunk issueIDs into batches under the driver placeholder limit.
- Verify opts.UseWispsTable matches the storage table.
- Retry; the queries are read-only aggregates.
- Check DB load/timeouts and add appropriate context timeout.
Example fix
// before
counts, err := deps.CountsByIssueIDs(ctx, manyIDs, domain.DepCountsOpts{})
// after
merged := map[string]*types.DependencyCounts{}
for batch := range slices.Chunk(manyIDs, 500) {
c, err := deps.CountsByIssueIDs(ctx, batch, domain.DepCountsOpts{})
if err != nil { return err }
for k, v := range c { merged[k] = v }
} Defensive patterns
Strategy: validation
Validate before calling
if len(issueIDs) == 0 { return map[string]*types.DependencyCounts{}, nil }
if len(issueIDs) > 500 { /* chunk before calling */ } Try / catch
if err != nil && strings.Contains(err.Error(), "CountsByIssueIDs (out)") {
// retry read-only aggregate or chunk the ID list
} Prevention
- Chunk ID batches for bulk count views.
- Confirm UseWispsTable matches the deps table.
- Set a sane context timeout for aggregate queries on large graphs.
- Retry is safe; counts are read-only.
When it happens
Trigger: CountsByIssueIDs(ctx, issueIDs, opts) with the outbound aggregate query failing: placeholder limit overflow with large ID lists, connection error, wrong table via UseWispsTable, or scan error in scanCounts.
Common situations: Board/bulk views counting deps for hundreds of issues at once; wisps vs issues table mismatch; DB under load timing out.
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.CountsByIssueIDs (in): %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/a7eadc627c9df55d.
Report an issue: GitHub.