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

  1. Increase the caller's context timeout for large cascades and retry.
  2. Retry the traversal; it is read-only and the partial discovered set can be reused.
  3. Reduce maxResults/batch size so each query completes within the timeout.
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/1740f38648aa927f. Report an issue: GitHub.