{"record":{"id":"88845fabc84287ed","repo":"gastownhall/beads","slug":"delete-check-dependents-w","errorCode":null,"errorMessage":"delete: check dependents: %w","messagePattern":"delete: check dependents: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/delete_role.go","lineNumber":109,"sourceCode":"\t\t}\n\t}\n\n\tidSet := make(map[string]bool, len(ids))\n\tfor _, id := range ids {\n\t\tidSet[id] = true\n\t}\n\n\t// The guard runs only when the request did not already say what to do\n\t// about dependents. Under Cascade there is nothing outside the set by\n\t// construction, which is why the expansion below is not asked about it.\n\t//\n\t// IT ASKS ABOUT EVERY NAMED ID, IN BOTH PLANES: the leaf says \"a NAMED ROW\n\t// that some row OUTSIDE the request depends on is refused\" with no wisp\n\t// exemption, and the unit-of-work body has always read it that way.\n\tif !req.Cascade {\n\t\texternal, err := ExternalDependentsBySourceInTx(ctx, tx, ids, idSet)\n\t\tif err != nil {\n\t\t\treturn publicops.DeleteResult{}, fmt.Errorf(\"delete: check dependents: %w\", err)\n\t\t}\n\t\tif !req.Force {\n\t\t\t// Request order, so the id a caller is told about is stable\n\t\t\t// across runs and across backends.\n\t\t\tfor _, id := range ids {\n\t\t\t\tif deps := external[id]; len(deps) > 0 {\n\t\t\t\t\treturn publicops.DeleteResult{}, &publicops.DependentsOutsideRequestError{\n\t\t\t\t\t\tIssueID:    id,\n\t\t\t\t\t\tDependents: deps,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\torphaned := make(map[string]bool)\n\t\t\tfor _, deps := range external {\n\t\t\t\tfor _, id := range deps {\n\t\t\t\t\torphaned[id] = true\n\t\t\t\t}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/delete_role.go#L91-L127","documentation":"This wraps a failure from ExternalDependentsBySourceInTx while DeleteInTx checks whether rows outside the request depend on the ids being deleted (only when req.Cascade is false). The expected domain refusal is DependentsOutsideRequestError; this error means the dependents query itself failed before an answer could be produced. It is a wrapper around a storage/driver failure.","triggerScenarios":"DeleteInTx with Cascade=false calls ExternalDependentsBySourceInTx; the SELECT against 'dependencies' or 'wisp_dependencies' fails for a non-'table not exist' reason (driver error, cancelled context, dead connection).","commonSituations":"Connection reset mid-delete; context timeout on a large batch; missing migration making the query error out rather than report table-not-exist; driver/backend version mismatch.","solutions":["Read the wrapped driver error; the message names the failing table ('query dependents from <table>')","Confirm both dependencies and wisp_dependencies tables exist / migrations are applied","Restore connectivity and retry the delete in a fresh transaction","If timeouts, increase the context budget or delete in smaller batches","If wisp_dependencies is intentionally absent on your backend, check whether optionalBlockedTable/isTableNotExistError covers your driver's error text"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check dependents outside the request using the public read path before deleting\nexternal, err := store.ExternalDependents(ctx, ids)\nif err != nil { return err }\nif len(external) > 0 && !req.Cascade && !req.Force { return fmt.Errorf(\"blocked by dependents: %v\", external) }","typeGuard":"var derr *publicops.DependentsOutsideRequestError\nif errors.As(err, &derr) { /* expected refusal: derr.IssueID, derr.Dependents */ }\n// else: 'delete: check dependents' wrapper => storage failure","tryCatchPattern":"_, err := store.Delete(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"delete: check dependents\") {\n    // wrapped driver error; inspect cause, retry in fresh tx\n}","preventionTips":["Probe dependents with a read before issuing unforced deletes","Ensure both dependency-plane migrations are applied","Keep delete contexts short-lived but adequately timed","Validate driver/backend version compatibility"],"tags":["database","delete","dependents","wrapper-error"],"backgroundTag":"db-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}