gastownhall/beads · critical
fetch child %s: %w
Error message
fetch child %s: %w
What it means
During ReconcileParents, fetching a child issue failed with a rate-limit-exhausted error, tripping the circuit breaker. Instead of continuing to hammer the API for every remaining link, the loop aborts immediately and returns this wrapped error alongside partial stats.
Source
Thrown at internal/linear/parent_reconcile.go:180
return entry{}, err
}
e := entry{issue: issue, client: client}
// Cache nil too — repeated lookups are still cheap.
fetched[identifier] = e
return e, nil
}
for _, link := range links {
if link.ChildIdentifier == "" || link.ParentIdentifier == "" {
continue
}
childE, err := fetchIssue(link.ChildIdentifier)
if err != nil {
// Rate-limit circuit breaker tripped — stop now rather than
// hammer the API for every remaining link.
if isRateLimitExhausted(err) {
return stats, fmt.Errorf("fetch child %s: %w", link.ChildIdentifier, err)
}
stats.Errors = append(stats.Errors,
fmt.Errorf("fetch child %s: %w", link.ChildIdentifier, err))
continue
}
if childE.issue == nil {
stats.NotFound = append(stats.NotFound, link.ChildIdentifier)
continue
}
parentE, err := fetchIssue(link.ParentIdentifier)
if err != nil {
if isRateLimitExhausted(err) {
return stats, fmt.Errorf("fetch parent %s: %w", link.ParentIdentifier, err)
}
stats.Errors = append(stats.Errors,
fmt.Errorf("fetch parent %s: %w", link.ParentIdentifier, err))
continueView on GitHub (pinned to 71377f2769)
Solutions
- Wait for the rate-limit window to reset, then re-run ReconcileParents (it resumes on remaining links).
- Reduce concurrency/batch size or spread reconciliation across intervals.
- Use a dedicated API token for reconciliation so other workloads don't drain the quota.
- Honor any Retry-After guidance and add longer backoff before re-running.
Defensive patterns
Strategy: retry
Try / catch
stats, err := linear.ReconcileParents(ctx, deps)
if err != nil && isRateLimitExhausted(err) {
time.Sleep(rateLimitResetWindow)
stats, err = linear.ReconcileParents(ctx, deps)
} Prevention
- Schedule reconciliation runs with generous spacing.
- Dedicate an API token to reconciliation jobs.
- Cap batch sizes and stop early on 429 responses.
When it happens
Trigger: fetchIssue(link.ChildIdentifier) returns an error for which isRateLimitExhausted(err) is true while reconciling parent links in ReconcileParents.
Common situations: Large backlogs of unlinked issues pushed through reconciliation in a short window; shared API token exhausted by other integrations; missing backoff between reconciliation runs.
Related errors
- max retries (%d) exceeded: %w
- no linear client
- Linear tracker not initialized
- fetching issues from team %s: %w
- no Linear client available
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e9f0e72796fc5cd0.
Report an issue: GitHub.