{"record":{"id":"358a10486b7ee764","repo":"gastownhall/beads","slug":"delete-affected-by-deletion-w","errorCode":null,"errorMessage":"delete: affected by deletion: %w","messagePattern":"delete: affected by deletion: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":163,"sourceCode":"\t\treturn result, nil\n\t}\n\n\tvar connected map[string]*types.Issue\n\tvar connectedIsWisp map[string]bool\n\tif params.UpdateTextReferences {\n\t\tdeletedSet := make(map[string]bool, len(allIDs))\n\t\tfor _, id := range allIDs {\n\t\t\tdeletedSet[id] = true\n\t\t}\n\t\tconnected, connectedIsWisp, err = u.collectConnectedIssues(ctx, allIDs, deletedSet)\n\t\tif err != nil {\n\t\t\treturn result, err\n\t\t}\n\t}\n\n\taffectedIssues, affectedWisps, err := u.issueRepo.AffectedByDeletion(ctx, regularIDs, wispIDs)\n\tif err != nil {\n\t\treturn result, fmt.Errorf(\"delete: affected by deletion: %w\", err)\n\t}\n\n\tif _, err := u.depRepo.DeleteAllForIDs(ctx, regularIDs, DepInsertOpts{}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop deps: %w\", err)\n\t}\n\tif _, err := u.depRepo.DeleteAllForIDs(ctx, wispIDs, DepInsertOpts{UseWispsTable: true}); err != nil {\n\t\treturn result, fmt.Errorf(\"delete: drop wisp deps: %w\", err)\n\t}\n\t// The SYNC-PLANE edges pointing at a deleted wisp, which are not the same\n\t// rows as the line above and are not reached by a foreign key: there is no\n\t// FK from dependencies to wisps, so `dependencies.depends_on_wisp_id` rows\n\t// survive their target unless they are deleted explicitly. Without this a\n\t// forced delete of a wisp left its durable dependent holding an edge into\n\t// a row that no longer exists — dangling, not orphaned, which is not what\n\t// issueops.DeleteRequest.Force promises. The store body has always done\n\t// this (issueops.deleteIssueRowInTx -> DeleteWispFromDependenciesInTx).\n\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)","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L145-L181","documentation":"deleteMany wraps errors from issueRepo.AffectedByDeletion, which finds remaining issues whose text references or dependencies point at the IDs being deleted. The 'delete: affected by deletion:' prefix marks this step; the driver error is preserved via %w. Depending on where the failure occurs, some delete steps (e.g. dependency drops) may already have partially completed.","triggerScenarios":"Any deleteMany invocation reaching the post-dry-run phase when AffectedByDeletion(ctx, regularIDs, wispIDs) fails — DB connection error, SQL error in the cross-reference query, storage unavailable mid-delete.","commonSituations":"Deletes of widely-referenced issues with many text references under load; Dolt restart mid-operation; schema drift on the issues/wisps tables.","solutions":["Inspect the wrapped AffectedByDeletion error to find the driver failure","Verify Dolt is reachable and check for a partially completed delete before retrying","Re-run the delete; the operation is designed to be resumable/re-runnable","If schema errors persist, run the beads migration path"],"exampleFix":"// before\nres, err := uc.DeleteIssues(ctx, ids, actor)\nif err != nil { return err }\n// after\nif err != nil {\n\tif strings.Contains(err.Error(), \"affected by deletion\") {\n\t\tlog.Printf(\"delete may be partially applied, verify state: %v\", err)\n\t}\n\treturn err\n}","handlingStrategy":"try-catch","validationCode":"if err := pingDolt(ctx); err != nil {\n\treturn fmt.Errorf(\"storage unavailable, deferring delete: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"res, err := uc.DeleteIssues(ctx, ids, actor)\nif err != nil && strings.Contains(err.Error(), \"affected by deletion\") {\n\t// failure late in the pipeline: verify delete state, then re-run\n\tlog.Printf(\"delete interrupted at cross-reference check: %v\", err)\n\treturn verifyAndRetryDelete(ctx, ids)\n}","preventionTips":["Verify issue state after a failed delete before retrying, since failure occurs mid-pipeline","Check Dolt health and logs for the exact phase that failed","Keep beads schema current so cross-reference queries succeed","Re-run deletes — the operation is idempotent for already-deleted IDs"],"tags":["go","delete","cross-references","wrapped-error"],"backgroundTag":"storage-operation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}