gastownhall/beads · error
iter dependents %s: %w
Error message
iter dependents %s: %w
What it means
collectDependents wraps any error from IterDependents in "iter dependents %s: %w", annotating which issue's dependents failed to iterate. BuildIssueDetails calls this while assembling detail payloads, so a storage/iterator failure surfaces with the offending id as context.
Source
Thrown at internal/workapi/detail.go:203
Priority: item.Issue.Priority,
Title: item.Issue.Title,
},
DependencyType: item.DependencyType,
}
}
// collectDependents streams the dependents and keeps only the
// identity-and-shape fields of each.
//
// be-4d36f2: hub beads with thousands of dependents made `bd show --json
// <hub>` allocate 5-13 GB marshaling full Issue records. The shallow shape
// preserves what callers consume (id, status, type, priority, title) and
// drops the free-form text; streaming keeps the full rows from piling up
// while we do it.
func collectDependents(ctx context.Context, src DetailSource, id string, isWisp bool) ([]*types.IssueWithDependencyMetadata, error) {
iter, err := src.IterDependents(ctx, id, isWisp)
if err != nil {
return nil, fmt.Errorf("iter dependents %s: %w", id, err)
}
defer iter.Close() //nolint:errcheck // read-only iterator
var out []*types.IssueWithDependencyMetadata
for iter.Next(ctx) {
item := iter.Value()
if item == nil {
continue
}
out = append(out, shallowDep(item))
}
if err := iter.Err(); err != nil {
return nil, fmt.Errorf("iter dependents %s: %w", id, err)
}
return out, nil
}
func collectComments(ctx context.Context, src DetailSource, id string, isWisp bool) ([]*types.Comment, error) {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped (%w) inner error for the root storage cause
- Retry the detail build with a fresh context if it was cancellation/deadline related
- Verify the DetailSource backend is healthy (connectivity, schema) before rebuilding
Example fix
// before
ctx := context.Background()
details, err := api.BuildIssueDetails(ctx, ids)
// after
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
details, err := api.BuildIssueDetails(ctx, ids)
if err != nil {
var target *storage.Err
if errors.As(err, &target) { /* reconnect / retry backend */ }
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: ensure the source backend is reachable before building details
if err := src.Ping(ctx); err != nil { return fmt.Errorf("detail source unavailable: %w", err) } Try / catch
details, err := api.BuildIssueDetails(ctx, ids)
if err != nil && strings.Contains(err.Error(), "iter dependents") {
return retryWithBackoff(ctx, 3, func() error {
var rerr error
details, rerr = api.BuildIssueDetails(ctx, ids)
return rerr
})
} Prevention
- Use a context with a sane timeout for detail builds
- Unwrap the %w chain to inspect the root storage error before retrying
- Monitor backend connectivity; reconnect on transient iterator failures
When it happens
Trigger: src.IterDependents returning an error for the given id (storage failure, closed backend, context cancellation during dependency iteration) inside BuildIssueDetails.
Common situations: Database connection dropped mid-detail-build; context deadline exceeded while iterating many dependents; storage seam misconfigured for the wisp/issue table being queried.
Related errors
- not found
- load wisp labels: %w
- edge %d %s->%s: checking planned blocking cycle: %w
- reading existing dependencies for %s: %w
- searching children of %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b744174eaf847b37.
Report an issue: GitHub.