{"record":{"id":"981e7043bd57f0cd","repo":"gastownhall/beads","slug":"previewdelete-list-deps-w","errorCode":null,"errorMessage":"previewDelete: list deps: %w","messagePattern":"previewDelete: list deps: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":306,"sourceCode":"\t\tpreview.Issues[iss.ID] = iss\n\t}\n\tfromWisps, err := u.issueRepo.GetByIDs(ctx, ids, IssueTableOpts{UseWispsTable: true})\n\tif err != nil && !dberrors.IsTableNotExist(err) {\n\t\treturn preview, fmt.Errorf(\"previewDelete: load wisps: %w\", err)\n\t}\n\tfor _, iss := range fromWisps {\n\t\tpreview.Issues[iss.ID] = iss\n\t}\n\n\tfor _, id := range ids {\n\t\tif _, ok := preview.Issues[id]; !ok {\n\t\t\tpreview.NotFound = append(preview.NotFound, id)\n\t\t}\n\t}\n\n\tdepRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionOut})\n\tif err != nil {\n\t\treturn preview, fmt.Errorf(\"previewDelete: list deps: %w\", err)\n\t}\n\tfor id, deps := range depRes.Outgoing {\n\t\tpreview.DepRecords[id] = deps\n\t}\n\twispDepRes, err := u.depRepo.ListByIssueIDs(ctx, ids, DepListOpts{Direction: DepDirectionOut, UseWispsTable: true})\n\tif err != nil && !dberrors.IsTableNotExist(err) {\n\t\treturn preview, fmt.Errorf(\"previewDelete: list wisp deps: %w\", err)\n\t}\n\tfor id, deps := range wispDepRes.Outgoing {\n\t\tpreview.DepRecords[id] = append(preview.DepRecords[id], deps...)\n\t}\n\n\tallIDs, err := u.issueRepo.FindAllDependents(ctx, ids)\n\tif err != nil {\n\t\treturn preview, fmt.Errorf(\"previewDelete: cascade expansion: %w\", err)\n\t}\n\tdeletedSet := make(map[string]bool, len(allIDs))\n\tfor _, id := range allIDs {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L288-L324","documentation":"This error wraps a failure from depRepo.ListByIssueIDs with Direction=DepDirectionOut in previewDelete, which collects outgoing dependency records that would be deleted along with the issues. Preview is read-only; failure aborts the preview only.","triggerScenarios":"PreviewDelete/PreviewDeleteWisp when the outgoing dependency bulk query on the main dependencies table fails: DB unreachable, timeout, oversized id list, or scan error.","commonSituations":"Transient connection loss during a dry-run; corrupted dependency rows; extremely wide cascade previews issuing heavy queries.","solutions":["Fix the driver-level error from the wrapped cause.","Retry the preview — it does not mutate data.","Batch the ids if the list is very large.","Check the dependencies table exists and is migrated."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate ids and connectivity before the preview:\nif len(ids) == 0 {\n    return nil\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    // distinguish connectivity vs data/scan errors\n}","tryCatchPattern":"preview, err := uc.PreviewDelete(ctx, ids)\nif err != nil && strings.Contains(err.Error(), \"previewDelete: list deps\") {\n    return fmt.Errorf(\"dependency lookup failed during preview: %w\", err)\n}","preventionTips":["Batch large delete sets to keep dep queries cheap","Verify dependencies table is migrated","Check connectivity before dry-runs","Retry freely — previews never mutate data"],"tags":["go","storage","dependencies","preview"],"backgroundTag":"dependency-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}