{"record":{"id":"11d9968fdf5384d5","repo":"gastownhall/beads","slug":"failed-to-create-dependency-w","errorCode":null,"errorMessage":"failed to create dependency: %w","messagePattern":"failed to create dependency: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/cook.go","lineNumber":926,"sourceCode":"\t\t\treturn fmt.Errorf(\"checking custom types: %w\", err)\n\t\t}\n\n\t\t// Create all issues\n\t\tif err := tx.CreateIssues(ctx, issues, actor); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create issues: %w\", err)\n\t\t}\n\n\t\t// Add labels\n\t\tfor _, l := range labels {\n\t\t\tif err := tx.AddLabel(ctx, l.issueID, l.label, actor); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to add label %s to %s: %w\", l.label, l.issueID, err)\n\t\t\t}\n\t\t}\n\n\t\t// Add dependencies\n\t\tfor _, dep := range deps {\n\t\t\tif err := tx.AddDependency(ctx, dep, actor); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create dependency: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cookFormulaResult{\n\t\tProtoID: protoID,\n\t\tCreated: len(issues),\n\t}, nil\n}\n\n// collectDependencies collects blocking dependencies from depends_on, needs, and waits_for fields.\n// This is the shared implementation used by both DB-persisted and in-memory subgraph cooking.","sourceCodeStart":908,"sourceCodeEnd":944,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/cook.go#L908-L944","documentation":"Wraps a failure from tx.AddDependency while persisting a cooked formula's dependency edges (DepBlocks/DepWaitsFor etc.) inside the single atomic transaction that creates issues, labels, and deps. When any single dependency insert fails the whole cook --persist transaction rolls back, leaving no partial subgraph. The wrapped cause carries the storage-level reason (duplicate edge, missing target issue, type not allowed, driver error).","triggerScenarios":"Running `bd cook <formula> --persist` (via persistCookFormula) where a step's depends_on/needs/waits_for produces an AddDependency call that storage rejects — e.g. the target issue was not among the created issues, a duplicate edge on the same (source,target) pair, or a driver-level constraint failure.","commonSituations":"A formula YAML whose waits_for spawner overlaps depends_on in a way the dedupe logic (GH#3783) doesn't cover; a custom/registered step type that maps to an issue ID missing from idMapping; Dolt driver errors or constraint violations during the transaction.","solutions":["Read the wrapped cause: if it's a duplicate/unknown-target dependency, fix the formula's depends_on/needs/waits_for so each edge references an existing step ID and isn't redundant with waits_for","Validate the formula (bd mol / formula lint) before persisting so step IDs and dependency references resolve","Re-run the command — the transaction rolled back cleanly, so no cleanup is needed; retry after fixing the formula","If the cause is a driver/storage error, check database connectivity and Dolt health before retrying"],"exampleFix":"# before (formula.yaml)\ndepends_on: [build, build]   # duplicate edge\n# after\ndepends_on: [build]","handlingStrategy":"validation","validationCode":"// Pre-validate the formula before persisting\nfor _, step := range f.Steps {\n    for _, depID := range append(append([]string{}, step.DependsOn...), step.Needs...) {\n        if _, ok := idMapping[depID]; !ok {\n            return fmt.Errorf(\"step %q references unknown dependency %q\", step.ID, depID)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := persistCookFormula(ctx, s, f); err != nil {\n    var cause error\n    errors.As(err, &cause) // inspect wrapped storage error\n    return fmt.Errorf(\"cook persist rolled back, formula unchanged: %w\", err)\n}","preventionTips":["Lint formulas so every depends_on/needs/waits_for references an existing step ID","Avoid redundant edges where waits_for spawner equals a depends_on target (GH#3783)","Use registered issue types or rely on automatic flattening to task before insert","Treat cook --persist as atomic: a failed run needs no manual cleanup, just fix and rerun"],"tags":["dependency","transaction","cook"],"backgroundTag":"dependency-creation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}