{"record":{"id":"193cf954aa09ae2c","repo":"gastownhall/beads","slug":"db-dependencysqlrepository-getblockinginfo-outbo","errorCode":null,"errorMessage":"db: DependencySQLRepository.GetBlockingInfo: outbound: %w","messagePattern":"db: DependencySQLRepository\\.GetBlockingInfo: outbound: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/dependency.go","lineNumber":502,"sourceCode":"\t\tBlockedBy: make(map[string][]string),\n\t\tBlocks:    make(map[string][]string),\n\t\tParent:    make(map[string]string),\n\t}\n\tif len(issueIDs) == 0 {\n\t\treturn info, nil\n\t}\n\n\ttable := pickDepTable(opts.UseWispsTable)\n\tidPlaceholders, idArgs := buildInPlaceholders(issueIDs)\n\n\t//nolint:gosec // G201: table and depTargetExpr are hardcoded constants\n\toutQ := fmt.Sprintf(\n\t\t\"SELECT issue_id, %s AS depends_on_id, type FROM %s WHERE issue_id IN (%s) AND type IN ('blocks', 'parent-child')\",\n\t\tdepTargetExpr, table, idPlaceholders,\n\t)\n\toutRows, err := r.scanBlockingRows(ctx, outQ, idArgs)\n\tif err != nil {\n\t\treturn domain.BlockingInfo{}, fmt.Errorf(\"db: DependencySQLRepository.GetBlockingInfo: outbound: %w\", err)\n\t}\n\n\t//nolint:gosec // G201: table and depTargetExpr are hardcoded constants\n\tinQ := fmt.Sprintf(\n\t\t\"SELECT issue_id, %s AS depends_on_id, type FROM %s WHERE %s IN (%s) AND type = 'blocks'\",\n\t\tdepTargetExpr, table, depTargetExpr, idPlaceholders,\n\t)\n\tinRows, err := r.scanBlockingRows(ctx, inQ, idArgs)\n\tif err != nil {\n\t\treturn domain.BlockingInfo{}, fmt.Errorf(\"db: DependencySQLRepository.GetBlockingInfo: inbound: %w\", err)\n\t}\n\n\tstatusIDs := make(map[string]struct{})\n\tfor _, row := range outRows {\n\t\tstatusIDs[row.dependsOnID] = struct{}{}\n\t}\n\tfor _, row := range inRows {\n\t\tstatusIDs[row.dependsOnID] = struct{}{}","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/dependency.go#L484-L520","documentation":"Wraps a failure from the outbound scanBlockingRows query in GetBlockingInfo, which selects outgoing 'blocks' and 'parent-child' edges for the given issues. The BlockingInfo result (Blocks/BlockedBy/Parent maps) cannot be built, so the caller gets an empty struct and this error.","triggerScenarios":"GetBlockingInfo(ctx, issueIDs, opts) with Direction-dependent outbound query failing: placeholder limit for many IDs, connection error, table mismatch (UseWispsTable), or scan error in scanBlockingRows.","commonSituations":"Rendering 'blocked by' panels for many issues; querying wisps with the wrong flag; long-running sessions whose connection was reaped by the server.","solutions":["Chunk issueIDs and merge the BlockingInfo results.","Verify opts.UseWispsTable matches where the deps live.","Retry on a fresh connection; read-only.","Confirm dep table schema matches expectations after upgrades (scan errors)."],"exampleFix":"// before\ninfo, err := deps.GetBlockingInfo(ctx, ids, domain.DepListOpts{UseWispsTable: false})\n// after\ninfo, err := deps.GetBlockingInfo(ctx, ids[:500], domain.DepListOpts{UseWispsTable: false})\nif err != nil { return err }\ninfo2, err := deps.GetBlockingInfo(ctx, ids[500:], domain.DepListOpts{UseWispsTable: false})\nmergeBlockingInfo(info, info2)","handlingStrategy":"validation","validationCode":"if len(issueIDs) == 0 { return domain.BlockingInfo{}, nil }\nif len(issueIDs) > 500 { /* chunk and merge BlockingInfo maps */ }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"GetBlockingInfo: outbound\") {\n    // retry read-only or chunk IDs and merge Blocks/Parent maps\n}","preventionTips":["Chunk ID lists for blocking-info panels rendering many issues.","Set UseWispsTable to match the deps storage.","Retry freely; queries are read-only.","Re-run migrations if scan errors appear after an upgrade."],"tags":["database","query","blocking"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}