gastownhall/beads · error
wisp id set: %w
Error message
wisp id set: %w
What it means
Thrown when the batched SELECT id FROM wisps WHERE id IN (...) fails to execute. After confirming the wisps table is non-empty, WispIDSetInTx queries ids in batches of queryBatchSize; any driver, connection, or SQL error in that query is wrapped here. The result determines which of the caller's ids are routed as wisps.
Source
Thrown at internal/storage/issueops/wisp_routing.go:92
} else if empty {
return set, nil
}
for start := 0; start < len(ids); start += queryBatchSize {
end := start + queryBatchSize
if end > len(ids) {
end = len(ids)
}
batch := ids[start:end]
placeholders := make([]string, len(batch))
args := make([]any, len(batch))
for i, id := range batch {
placeholders[i] = "?"
args[i] = id
}
q := fmt.Sprintf("SELECT id FROM wisps WHERE id IN (%s)", strings.Join(placeholders, ","))
rows, err := tx.QueryContext(ctx, q, args...)
if err != nil {
return nil, fmt.Errorf("wisp id set: %w", err)
}
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("wisp id set: scan: %w", err)
}
set[id] = struct{}{}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("wisp id set: rows: %w", err)
}
}
return set, nil
}
// partitionByWispSet splits ids into (wispIDs, permIDs) using the providedView on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped driver error for connection vs missing-table vs syntax causes.
- Run migrations to recreate the wisps table if it is missing.
- Retry the operation once the database connection is healthy.
- Check server logs if the batch query was killed for resource limits.
Example fix
// before: wisps table dropped DROP TABLE wisps; // after: recreate via migration CREATE TABLE wisps (id VARCHAR(255) NOT NULL PRIMARY KEY, ...);
Defensive patterns
Strategy: retry
Validate before calling
var exists string
if err := db.QueryRow("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME='wisps'").Scan(&exists); err != nil {
return errors.New("wisps table missing: run beads migration")
} Try / catch
err := retry.Do(func() error {
_, err := issueops.GetIssuesByIDsInTx(ctx, tx, ids)
return err
}, retry.Attempts(3), retry.Delay(500*time.Millisecond)) Prevention
- Keep the wisps table in place; never drop it during rolling upgrades.
- Retry routing operations — id set computation is read-only and safe to repeat.
- Check server logs if IN-batch queries are killed for resources.
- Keep batches within queryBatchSize (library handles this; do not bypass).
When it happens
Trigger: Calling DeleteInTx, GetIssuesByIDsInTx, ExecuteAddDependencies, or ReconcileChildCounters with ids present in the codebase while the wisps SELECT fails: broken connection, wisps table dropped mid-operation, or SQL error from a malformed batch.
Common situations: Schema migration removed/renamed the wisps table while old code still runs; connection dropped during a mixed write/read transaction; server killed the IN-query for resource reasons.
Related errors
- wisp id set: probe: %w
- wisp id set: scan: %w
- wisp id set: rows: %w
- partition wisp ids: probe: %w
- partition wisp ids: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2aa6a670bdf4da5d.
Report an issue: GitHub.