gastownhall/beads · error
delete: drop sync-plane edges into deleted wisps: %w
Error message
delete: drop sync-plane edges into deleted wisps: %w
What it means
Wraps failure of the explicit sync-plane cleanup: dependencies.depends_on_wisp_id rows pointing at deleted wisps have no foreign key, so they are deleted separately (regular-table DeleteAllForIDs with the wisp IDs). If this DELETE fails, dangling edges would remain, violating Force-delete semantics, so the operation aborts with this error.
Source
Thrown at internal/storage/domain/issue_delete.go:181
return result, fmt.Errorf("delete: affected by deletion: %w", err)
}
if _, err := u.depRepo.DeleteAllForIDs(ctx, regularIDs, DepInsertOpts{}); err != nil {
return result, fmt.Errorf("delete: drop deps: %w", err)
}
if _, err := u.depRepo.DeleteAllForIDs(ctx, wispIDs, DepInsertOpts{UseWispsTable: true}); err != nil {
return result, fmt.Errorf("delete: drop wisp deps: %w", err)
}
// The SYNC-PLANE edges pointing at a deleted wisp, which are not the same
// rows as the line above and are not reached by a foreign key: there is no
// FK from dependencies to wisps, so `dependencies.depends_on_wisp_id` rows
// survive their target unless they are deleted explicitly. Without this a
// forced delete of a wisp left its durable dependent holding an edge into
// a row that no longer exists — dangling, not orphaned, which is not what
// issueops.DeleteRequest.Force promises. The store body has always done
// this (issueops.deleteIssueRowInTx -> DeleteWispFromDependenciesInTx).
if _, err := u.depRepo.DeleteAllForIDs(ctx, wispIDs, DepInsertOpts{}); err != nil {
return result, fmt.Errorf("delete: drop sync-plane edges into deleted wisps: %w", err)
}
if _, err := u.labelRepo.DeleteAllForIDs(ctx, regularIDs, LabelOpts{}); err != nil {
return result, fmt.Errorf("delete: drop labels: %w", err)
}
if _, err := u.labelRepo.DeleteAllForIDs(ctx, wispIDs, LabelOpts{UseWispsTable: true}); err != nil {
return result, fmt.Errorf("delete: drop wisp labels: %w", err)
}
if _, err := u.eventsRepo.DeleteAllForIDs(ctx, regularIDs, RecordEventOpts{}); err != nil {
return result, fmt.Errorf("delete: drop events: %w", err)
}
if _, err := u.eventsRepo.DeleteAllForIDs(ctx, wispIDs, RecordEventOpts{UseWispsTable: true}); err != nil {
return result, fmt.Errorf("delete: drop wisp events: %w", err)
}
issuesDeleted, err := u.issueRepo.DeleteByIDs(ctx, regularIDs, IssueTableOpts{})
if err != nil {
return result, fmt.Errorf("delete: drop issue rows: %w", err)
}View on GitHub (pinned to 71377f2769)
Solutions
- Check the regular dependencies table exists and is writable in the embedded DB.
- Retry the delete — transactional cleanup prevents partial dangling edges.
- Inspect the wrapped cause for lock/permission errors and resolve them.
- Avoid deleting very large wisp sets in one call; chunk the IDs.
Defensive patterns
Strategy: validation
Validate before calling
if err := ctx.Err(); err != nil { return err }
exists, err := tableExists(ctx, "dependencies"); if err != nil || !exists { return fmt.Errorf("sync-plane dependencies table missing") } Type guard
var dbe *storage.DBError
if errors.As(err, &dbe) { /* inspect driver cause */ } Try / catch
if err := store.DeleteWisps(ctx, ids, opts); err != nil {
if strings.Contains(err.Error(), "drop sync-plane edges") {
// retry; do not assume deletions are partial — op is transactional
}
} Prevention
- Ensure schema migrations are applied before deleting wisps.
- Keep context deadlines generous for forced deletes with dependents.
- Monitor for lock wait timeouts under concurrent load.
- Batch wisp deletions into modest ID sets.
When it happens
Trigger: A forced delete involving wisps where the regular dependencies table cannot be written (missing table, lock contention, driver error, cancelled context) during the third depRepo.DeleteAllForIDs call.
Common situations: Schema drift where the sync-plane dependencies table is absent; DB under heavy write load causing lock wait timeouts; connection dropped mid-batch on large wisp deletions.
Related errors
- delete: drop wisp deps: %w
- failed to remove relates-to %s -> %s: %w
- failed to get dependencies for %s: %w
- db: DependencySQLRepository.GetWispDependencyRecordsForIDs:
- add deps: classify sources: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f90a5b65988fee99.
Report an issue: GitHub.