{"record":{"id":"98581d177bc9ad4d","repo":"gastownhall/beads","slug":"delete-drop-wisp-rows-w","errorCode":null,"errorMessage":"delete: drop wisp rows: %w","messagePattern":"delete: drop wisp rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":202,"sourceCode":"\t\treturn result, fmt.Errorf(\"delete: drop labels: %w\", err)\n\t}\n\tif _, err := u.labelRepo.DeleteAllForIDs(ctx, wispIDs, LabelOpts{UseWispsTable: true}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop wisp labels: %w\", err)\n\t}\n\tif _, err := u.eventsRepo.DeleteAllForIDs(ctx, regularIDs, RecordEventOpts{}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop events: %w\", err)\n\t}\n\tif _, err := u.eventsRepo.DeleteAllForIDs(ctx, wispIDs, RecordEventOpts{UseWispsTable: true}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop wisp events: %w\", err)\n\t}\n\n\tissuesDeleted, err := u.issueRepo.DeleteByIDs(ctx, regularIDs, IssueTableOpts{})\n\tif err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop issue rows: %w\", err)\n\t}\n\twispsDeleted, err := u.issueRepo.DeleteByIDs(ctx, wispIDs, IssueTableOpts{UseWispsTable: true})\n\tif err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop wisp rows: %w\", err)\n\t}\n\tresult.DeletedCount = issuesDeleted + wispsDeleted\n\n\tif params.UpdateTextReferences && len(connected) > 0 {\n\t\trefs, err := u.rewriteTextReferences(ctx, allIDs, connected, connectedIsWisp, actor)\n\t\tif err != nil {\n\t\t\treturn result, fmt.Errorf(\"delete: rewrite text references: %w\", err)\n\t\t}\n\t\tresult.ReferencesUpdated = refs\n\t}\n\n\tif err := u.issueRepo.RecomputeIsBlocked(ctx, affectedIssues, affectedWisps); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: recompute is_blocked: %w\", err)\n\t}\n\n\treturn result, nil\n}\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L184-L220","documentation":"Same final row delete as 'drop issue rows' but on the wisps table: issueRepo.DeleteByIDs with UseWispsTable:true. Failure means wisp rows could not be removed after their dependencies/labels/events were dropped; the delete aborts with this wrapped error.","triggerScenarios":"DeleteWisp/DeleteWisps (or mixed sets) where the wisps table rejects the DELETE (missing table, constraint, permissions, lock) or the connection/context fails at this step.","commonSituations":"Older embedded DB without the wisps table; lock contention during large wisp batches; transient connection loss; disk full on the embedded Dolt store.","solutions":["Confirm the wisps table exists and is writable; migrate if stale.","Retry the delete — transactional scope keeps state consistent.","Check the wrapped cause for constraint/lock/permission details.","Free disk space / vacuum the embedded store if resource exhaustion is indicated."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := ctx.Err(); err != nil { return err }\nexists, err := tableExists(ctx, \"wisps\"); if err != nil || !exists { return fmt.Errorf(\"wisps table missing — migrate schema\") }","typeGuard":"var dbe *storage.DBError\nif errors.As(err, &dbe) { /* inspect driver cause */ }","tryCatchPattern":"if err := store.DeleteWisps(ctx, ids, opts); err != nil {\n    if strings.Contains(err.Error(), \"delete: drop wisp rows:\") { /* check cause: locks, disk, perms */ }\n}","preventionTips":["Migrate embedded stores lacking the wisps table.","Watch disk space on the embedded Dolt data directory.","Avoid concurrent writers to the same store.","Use moderate batch sizes for wisp deletion."],"tags":["storage","database","wisps","delete"],"backgroundTag":"issue-row-delete-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}