gastownhall/beads · error
count wisp events: %w
Error message
count wisp events: %w
What it means
DeleteResolvedSetInTx aborts when it cannot count rows in the "wisp_events" table for the wisp IDs being deleted. This wraps the driver error from CountRowsForIssueIDsInTx and completes the events count for the dry-run delete result.
Source
Thrown at internal/storage/issueops/delete.go:235
return nil, fmt.Errorf("count wisp dependencies: %w", err)
}
depsCount += wispDepsCount
if labelsCount, err = CountRowsForIssueIDsInTx(ctx, tx, "labels", set.RegularIDs); err != nil {
return nil, fmt.Errorf("count labels: %w", err)
}
wispLabelsCount, err := CountRowsForIssueIDsInTx(ctx, tx, "wisp_labels", set.WispIDs)
if err != nil {
return nil, fmt.Errorf("count wisp labels: %w", err)
}
labelsCount += wispLabelsCount
if eventsCount, err = CountRowsForIssueIDsInTx(ctx, tx, "events", set.RegularIDs); err != nil {
return nil, fmt.Errorf("count events: %w", err)
}
wispEventsCount, err := CountRowsForIssueIDsInTx(ctx, tx, "wisp_events", set.WispIDs)
if err != nil {
return nil, fmt.Errorf("count wisp events: %w", err)
}
eventsCount += wispEventsCount
for i := 0; i < len(set.All); i += deleteBatchSize {
end := i + deleteBatchSize
if end > len(set.All) {
end = len(set.All)
}
batch := set.All[i:end]
batchInClause, batchArgs := buildSQLInClause(batch)
for _, depTable := range []string{"dependencies", "wisp_dependencies"} {
rows, err := tx.QueryContext(ctx,
fmt.Sprintf(`SELECT issue_id FROM %s WHERE %s`, depTable, depTargetIn("", batchInClause)),
batchArgs...)
if err != nil {
if optionalBlockedTable(depTable) && isTableNotExistError(err) {
continueView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error to identify missing-table vs connection causes.
- Apply schema migrations so wisp_events exists.
- Retry with a fresh transaction if the cause was transient.
- Confirm backend/driver support for wisp tables (see the storage boundary docs).
Example fix
// before
res, err := store.DeleteIssuesInTx(ctx, tx, ids)
// after
if err := migrator.EnsureSchema(ctx); err != nil {
return fmt.Errorf("schema out of date: %w", err)
}
res, err := store.DeleteIssuesInTx(ctx, tx, ids) Defensive patterns
Strategy: validation
Validate before calling
var name string
err := db.QueryRowContext(ctx,
`SELECT table_name FROM information_schema.tables WHERE table_name = 'wisp_events'`).Scan(&name)
if err != nil {
return errors.New("wisp_events missing: run schema migration before deleting wisps")
} Try / catch
res, err := store.DeleteInTx(ctx, tx, ids)
if err != nil && strings.Contains(err.Error(), "wisp_events") {
return fmt.Errorf("schema missing wisp_events; run migration: %w", err)
} Prevention
- Align on-disk schema version with the beads binary version.
- Include wisp-table presence in pre-flight health checks.
- Back up the database before bulk deletes so corruption is recoverable.
When it happens
Trigger: Calling DeleteIssuesInTx/DeleteInTx when wisp_events does not exist (older schema, unsupported embedded driver) or the connection/transaction fails at this point in the count sequence.
Common situations: Version mismatch between beads binary and on-disk schema (wisp_events not yet migrated); Dolt server restart mid-delete; disk I/O errors on embedded databases.
Related errors
- count wisp labels: %w
- count wisp dependencies: %w
- count labels: %w
- count events: %w
- failed to begin transaction: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1962535a4caa41aa.
Report an issue: GitHub.