{"record":{"id":"ef4e8dc93d038d7c","repo":"gastownhall/beads","slug":"delete-drop-issue-rows-w","errorCode":null,"errorMessage":"delete: drop issue rows: %w","messagePattern":"delete: drop issue rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":198,"sourceCode":"\tif _, err := u.depRepo.DeleteAllForIDs(ctx, wispIDs, DepInsertOpts{}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop sync-plane edges into deleted wisps: %w\", err)\n\t}\n\tif _, err := u.labelRepo.DeleteAllForIDs(ctx, regularIDs, LabelOpts{}); err != nil {\n\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}","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L180-L216","documentation":"This error means the final row-level delete of the regular issues themselves failed: issueRepo.DeleteByIDs on the main issues table. This is the step that actually removes issue rows after all child data has been dropped; failure aborts the delete.","triggerScenarios":"DeleteIssue/DeleteIssues calls where the issues table cannot be written (FK constraint from an un-deleted child table, permissions, lock contention) or the connection/context fails before the DELETE completes.","commonSituations":"Foreign-key constraint due to a child table not covered by the cascade; DB user lacking DELETE privilege; deadlock with a concurrent writer; stale schema missing expected structure.","solutions":["Inspect the wrapped cause for FK violations and find the child table blocking the row delete.","Retry the delete; earlier cascade steps are transactional so state is intact.","Verify DELETE privileges on the issues table.","Run migrations / bd doctor if the schema may be stale."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if err := ctx.Err(); err != nil { return err }\n// prefer the dry run to surface blockers before real deletion\nres, err := store.DeleteIssues(ctx, ids, DeleteIssuesParams{DryRun: true})\nif err != nil { return err }","typeGuard":"var blocked *domain.DeleteBlockedError\nif errors.As(err, &blocked) { /* blocked by external dependents: handle or use Force */ }","tryCatchPattern":"if err := store.DeleteIssues(ctx, ids, opts); err != nil {\n    var blocked *domain.DeleteBlockedError\n    if errors.As(err, &blocked) { /* resolve dependents */ }\n    if strings.Contains(err.Error(), \"delete: drop issue rows:\") { /* check FK/perm cause */ }\n}","preventionTips":["Use DryRun first to preview cascade counts and blockers.","Resolve external dependents (or set Force/Cascade deliberately) before deleting.","Grant DELETE privileges on the issues table.","Keep schema migrations current."],"tags":["storage","database","delete","issues"],"backgroundTag":"issue-row-delete-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}