{"record":{"id":"5320b4c212dcada4","repo":"gastownhall/beads","slug":"delete-list-dependents-w","errorCode":null,"errorMessage":"delete: list dependents: %w","messagePattern":"delete: list dependents: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":232,"sourceCode":"\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\n// externalDependents finds the direct dependents of each id in ids that are\n// not themselves in ids, across both the issue and wisp dependency tables.\n// The result maps deletion-set id -> external dependent ids (unsorted).\nfunc (u *issueUseCaseImpl) externalDependents(ctx context.Context, ids []string) (map[string][]string, error) {\n\tidSet := make(map[string]bool, len(ids))\n\tfor _, id := range ids {\n\t\tidSet[id] = true\n\t}\n\n\tissueRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionIn})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"delete: list dependents: %w\", err)\n\t}\n\twispRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionIn, UseWispsTable: true})\n\tif err != nil && !dberrors.IsTableNotExist(err) {\n\t\treturn nil, fmt.Errorf(\"delete: list wisp dependents: %w\", err)\n\t}\n\n\tout := map[string][]string{}\n\tseen := map[string]map[string]bool{}\n\tfor _, res := range []DepBulkResult{issueRes, wispRes} {\n\t\tfor target, deps := range res.Incoming {\n\t\t\tfor _, d := range deps {\n\t\t\t\tif d.IssueID == \"\" || idSet[d.IssueID] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif seen[target] == nil {\n\t\t\t\t\tseen[target] = map[string]bool{}\n\t\t\t\t}\n\t\t\t\tif seen[target][d.IssueID] {","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L214-L250","documentation":"This error wraps a failure from depRepo.ListByIssueIDs with Direction=DepDirectionIn (incoming dependencies) in externalDependents, which finds direct dependents of the ids being deleted that are not themselves in the delete set. The wisp-table variant tolerates a missing wisps table, but a failure on the main dependencies table is fatal for the delete flow.","triggerScenarios":"deleteMany -> externalDependents when the incoming-dependency bulk query on the regular dependencies table fails: DB unreachable, malformed ids, query timeout, or driver-level scan error.","commonSituations":"Database connection loss during delete; extremely long id lists producing oversized IN clauses; corrupted dependency rows failing to scan into types.Dependency.","solutions":["Check the wrapped driver error — fix connectivity or the underlying storage issue first.","Reduce batch size if the id list is very large, and call delete in chunks.","Retry the operation; the query is read-only and safe to re-run.","Verify the dependencies table exists and is migrated in this database."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Validate ids before the call:\nfor _, id := range ids {\n    if id == \"\" {\n        return errors.New(\"empty issue id in delete set\")\n    }\n}\nif err := store.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"db unreachable: %w\", err)\n}","typeGuard":"var dbErr *dberrors.DBError\nif errors.As(err, &dbErr) {\n    // inspect dbErr.Code to distinguish connectivity vs scan errors\n}","tryCatchPattern":"_, err := uc.DeleteIssues(ctx, ids, opts)\nif err != nil && strings.Contains(err.Error(), \"delete: list dependents\") {\n    // read-only phase failed; safe to retry with backoff\n    return retryWithBackoff(func() error { _, err := uc.DeleteIssues(ctx, ids, opts); return err })\n}","preventionTips":["Chunk very large delete id lists","Check DB connectivity before bulk deletes","Keep schema migrations current","Log wrapped causes for driver-level diagnosis"],"tags":["go","storage","dependencies","delete"],"backgroundTag":"dependency-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}