{"record":{"id":"cfcad95c1fd3bb9a","repo":"gastownhall/beads","slug":"dependency-graph-query-s-w","errorCode":null,"errorMessage":"dependency graph: query %s: %w","messagePattern":"dependency graph: query (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/cycles.go","lineNumber":102,"sourceCode":"func AppendBlockingGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string) error {\n\treturn appendDependencyGraphInTx(ctx, tx, depTables, graph, false)\n}\n\n// AppendSchedulingGraphInTx adds blocks, conditional-blocks, and parent-child\n// edges to graph for validating mutations against the combined scheduling\n// graph. DetectCycles intentionally continues to use AppendBlockingGraphInTx.\nfunc AppendSchedulingGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string) error {\n\treturn appendDependencyGraphInTx(ctx, tx, depTables, graph, true)\n}\n\nfunc appendDependencyGraphInTx(ctx context.Context, tx DBTX, depTables []string, graph map[string][]string, includeParentChild bool) error {\n\tfor _, depTable := range depTables {\n\t\trows, err := tx.QueryContext(ctx, fmt.Sprintf(`\n\t\t\tSELECT issue_id, %s AS depends_on_id, type\n\t\t\tFROM %s\n\t\t`, DepTargetExpr, depTable))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"dependency graph: query %s: %w\", depTable, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar issueID, dependsOnID, depType string\n\t\t\tif err := rows.Scan(&issueID, &dependsOnID, &depType); err != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"dependency graph: scan %s: %w\", depTable, err)\n\t\t\t}\n\t\t\tt := types.DependencyType(depType)\n\t\t\tif t == types.DepBlocks || t == types.DepConditionalBlocks || (includeParentChild && t == types.DepParentChild) {\n\t\t\t\tgraph[issueID] = append(graph[issueID], dependsOnID)\n\t\t\t}\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"dependency graph: rows %s: %w\", depTable, err)\n\t\t}\n\t}\n\treturn nil","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/cycles.go#L84-L120","documentation":"appendDependencyGraphInTx failed querying a dependency table (per depTable in the given list) while assembling the blocking/scheduling dependency graph for cycle detection. The table name is interpolated into the message; the driver error is wrapped. This aborts the cycle-check, and the caller treats graph-build failure as fatal for the operation.","triggerScenarios":"QueryContext over a dependency table fails during AppendBlockingGraphInTx / AppendSchedulingGraphInTx — missing table, locked DB, connection loss mid-cycle-check.","commonSituations":"Schema drift (dependency table absent after partial migration); storage contention while another transaction mutates dependencies; transient driver failures on large graphs.","solutions":["Inspect the wrapped driver error and the named table to find the storage-level cause","Apply pending migrations so all dependency tables exist","Retry the operation in a fresh transaction; reduce concurrent dependency writes during cycle checks"],"exampleFix":"// before\n// retry blindly\n// after\nif strings.Contains(err.Error(), \"no such table\") { runMigrations(); retry() }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := AddDependency(ctx, ...); err != nil {\n    if strings.HasPrefix(err.Error(), \"dependency graph: query \") {\n        // backoff and retry the operation in a new transaction\n    }\n    return err\n}","preventionTips":["Keep schema migrations current","Avoid heavy concurrent dependency mutations","Use bounded retries with backoff on cycle-check operations"],"tags":["database","dependency-graph","query","cycle-detection"],"backgroundTag":"dependency-graph-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}