gastownhall/beads · error
iterate wisp dependents: %w
Error message
iterate wisp dependents: %w
What it means
After consuming a batch of dependent rows, the traversal checks rows.Err() and wraps any iteration-level error with this message. This catches errors that surface lazily during row iteration (e.g. connection reset mid-result-set) rather than at query time. The traversal aborts and returns the partial discovered set.
Source
Thrown at internal/storage/issueops/bulk_ops.go:406
if err != nil {
return discovered, fmt.Errorf("query wisp dependents: %w", err)
}
for rows.Next() {
var depID string
if err := rows.Scan(&depID); err != nil {
_ = rows.Close()
return discovered, fmt.Errorf("scan wisp dependent: %w", err)
}
if !seen[depID] {
seen[depID] = true
discovered[depID] = true
toProcess = append(toProcess, depID)
}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return discovered, fmt.Errorf("iterate wisp dependents: %w", err)
}
}
return discovered, nil
}
// GetRepoMtimeInTx returns the cached mtime (nanoseconds) for a repo path.
// Returns 0 if no cache entry exists.
func GetRepoMtimeInTx(ctx context.Context, tx *sql.Tx, repoPath string) (int64, error) {
var mtimeNs int64
err := tx.QueryRowContext(ctx,
`SELECT mtime_ns FROM repo_mtimes WHERE repo_path = ?`, repoPath).Scan(&mtimeNs)
if err != nil {
return 0, nil
}
return mtimeNs, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Increase the caller's context timeout for large cascades and retry.
- Retry the traversal; it is read-only and the partial discovered set can be reused.
- Reduce maxResults/batch size so each query completes within the timeout.
- Check network stability to the storage server if errors recur.
Example fix
// before ctx := context.Background() ids, _ := store.FindWispDependentsRecursive(ctx, tx, rootID, max) // killed at server query timeout // after ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() ids, err := store.FindWispDependentsRecursive(ctx, tx, rootID, max)
Defensive patterns
Strategy: retry
Validate before calling
if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < 30*time.Second {
return errors.New("context deadline too short for dependency traversal; extend timeout")
} Try / catch
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
ids, err := store.FindWispDependentsRecursive(ctx, tx, rootID, max)
if err != nil && strings.Contains(err.Error(), "iterate wisp dependents:") {
// streaming error: retry with longer timeout
return retryWithLongerDeadline(ctx, tx, rootID, max)
} Prevention
- Give traversal calls generous context timeouts.
- Bound cascade size (maxResults) so result sets stream quickly.
- Retry read-only traversals freely; they cannot corrupt state.
When it happens
Trigger: Calling FindWispDependentsRecursiveInTx when the result set is interrupted while streaming — network drop, server-side timeout/kill of the query, or context cancellation while rows are being read.
Common situations: Long-running traversal over a large dependency graph exceeding a query timeout; context deadline exceeded because the caller set a short timeout; network blip to a remote Dolt server.
Related errors
- failed to iterate existing issues for prefix %q: %w
- failed to begin transaction: %w
- iterate dirty config diff: %w
- %s close timed out after %v
- db: GetAllConfig: read: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1740f38648aa927f.
Report an issue: GitHub.