{"record":{"id":"94bc7d01cc69f20b","repo":"gastownhall/beads","slug":"delete-count-deps-w","errorCode":null,"errorMessage":"delete: count deps: %w","messagePattern":"delete: count deps: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue_delete.go","lineNumber":480,"sourceCode":"// (batch)` was run per 50-id batch, so an edge whose two ends fell in\n// different batches matched twice. Keying by the edge itself removes that\n// hazard rather than trading it for another: a row is counted once whether it\n// is reached as somebody's outbound edge, somebody's inbound edge, or both.\nfunc (u *issueUseCaseImpl) countDeletedDependencies(ctx context.Context, allIDs []string) (int, error) {\n\tif len(allIDs) == 0 {\n\t\treturn 0, nil\n\t}\n\tseen := make(map[string]bool)\n\tfor _, useWisps := range []bool{false, true} {\n\t\tedges, err := u.depRepo.ListByIssueIDs(ctx, allIDs, DepListOpts{\n\t\t\tDirection:     DepDirectionBoth,\n\t\t\tUseWispsTable: useWisps,\n\t\t})\n\t\tif err != nil {\n\t\t\tif useWisps && dberrors.IsTableNotExist(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn 0, fmt.Errorf(\"delete: count deps: %w\", err)\n\t\t}\n\t\tfor _, side := range []map[string][]*types.Dependency{edges.Outgoing, edges.Incoming} {\n\t\t\tfor _, list := range side {\n\t\t\t\tfor _, dep := range list {\n\t\t\t\t\tif dep == nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// (source, target) is unique per table: the writer refuses a\n\t\t\t\t\t// second edge for a pair, retyping included.\n\t\t\t\t\tseen[fmt.Sprintf(\"%t\\x00%s\\x00%s\", useWisps, dep.IssueID, dep.DependsOnID)] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn len(seen), nil\n}\n","sourceCodeStart":462,"sourceCodeEnd":497,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue_delete.go#L462-L497","documentation":"Wraps a failure from depRepo.ListByIssueIDs in countDeletedDependencies, which counts dependency edges that a deleteMany will remove across both the durable and wisp dependency planes. A table-not-exist error on the wisp pass is tolerated; this error fires for any other failure, including failures on the durable (first) pass.","triggerScenarios":"deleteMany of issues that have dependency edges, where ListByIssueIDs fails on either plane — locked database, dropped connection, context cancellation, or a driver-level SQL error.","commonSituations":"Deleting from a store while a Dolt compaction/GC runs; connection pool exhaustion under many parallel bd commands; canceled deletes; a dependency table corrupted or locked by another transaction.","solutions":["Inspect the wrapped cause and fix the underlying storage issue (lock, connectivity, corruption).","Retry the delete when no other process is writing to the store.","Use a fresh, non-canceled context for the operation.","Run bd doctor to check database health if the error persists.","Verify the dependencies (and wisp_dependencies) tables exist and match your driver's expected schema."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check dependency tables are readable before delete\nif _, err := usecase.GetDependencies(ctx, firstID); err != nil {\n    return fmt.Errorf(\"dependency store unreadable: %w\", err)\n}","typeGuard":"func isCountDepsErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"delete: count deps:\")\n}","tryCatchPattern":"err := usecase.DeleteMany(ctx, ids)\nif err != nil && strings.Contains(err.Error(), \"delete: count deps:\") {\n    cause := errors.Unwrap(err)\n    if !dberrors.IsTableNotExist(cause) {\n        // retry with backoff or surface a storage-health problem\n    }\n}","preventionTips":["Avoid deleting during Dolt maintenance (GC/compaction) windows","Limit parallel bd commands against one store to prevent pool exhaustion","Retry transient storage errors with backoff before aborting","Verify dependency-table schema matches your driver version after upgrades"],"tags":["storage","database","dependencies","delete"],"backgroundTag":"database-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}