{"record":{"id":"a8032ea0789f0587","repo":"gastownhall/beads","slug":"node-q-dep-d-has-empty-target","errorCode":null,"errorMessage":"node %q: dep %d has empty target","messagePattern":"node %q: dep (.+?) has empty target","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/graph_apply.go","lineNumber":581,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tparentKey := node.effectiveParentKey()\n\t\tif parentKey != \"\" && !seenKeys[parentKey] {\n\t\t\tfound := false\n\t\t\tfor _, other := range plan.Nodes {\n\t\t\t\tif other.Key == parentKey {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !found {\n\t\t\t\treturn fmt.Errorf(\"node %q: parent key %q not found in plan\", node.Key, parentKey)\n\t\t\t}\n\t\t}\n\t\tfor j, dep := range node.Deps {\n\t\t\tif dep.Target == \"\" {\n\t\t\t\treturn fmt.Errorf(\"node %q: dep %d has empty target\", node.Key, j)\n\t\t\t}\n\t\t\tif dep.Type != \"\" {\n\t\t\t\tdt := types.DependencyType(dep.Type)\n\t\t\t\tif !dt.IsValid() {\n\t\t\t\t\treturn fmt.Errorf(\"node %q: dep %d: invalid dependency type %q\", node.Key, j, dep.Type)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor i, edge := range plan.Edges {\n\t\tif edge.FromKey != \"\" && !seenKeys[edge.FromKey] {\n\t\t\treturn fmt.Errorf(\"edge %d: from key %q not found in plan\", i, edge.FromKey)\n\t\t}\n\t\tif edge.ToKey != \"\" && !seenKeys[edge.ToKey] {\n\t\t\treturn fmt.Errorf(\"edge %d: to key %q not found in plan\", i, edge.ToKey)\n\t\t}\n\t\tif edge.FromKey == \"\" && edge.FromID == \"\" {","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/graph_apply.go#L563-L599","documentation":"Each entry in a node's deps array must have a non-empty `target`. An empty target makes the dependency unresolvable, so validation rejects the plan with the node key and dep index.","triggerScenarios":"`bd graph apply` where plan.nodes[i].deps[j] has `\"target\": \"\"` or the target field is omitted.","commonSituations":"Programmatic plan generation that emits dep objects with unfilled targets; hand-editing plans and clearing a target; template loops emitting placeholder dep entries.","solutions":["Set deps[j].target to the key (or id) of the dependency target node","Remove the empty dep entry if it is spurious","Fix the generator so targets are always populated"],"exampleFix":"// before\n{\"key\": \"deploy\", \"deps\": [{\"type\": \"blocks\", \"target\": \"\"}]}\n// after\n{\"key\": \"deploy\", \"deps\": [{\"type\": \"blocks\", \"target\": \"build\"}]}","handlingStrategy":"validation","validationCode":"for i, n := range plan.Nodes {\n\tfor j, d := range n.Deps {\n\t\tif d.Target == \"\" { return fmt.Errorf(\"node %s dep %d empty target\", n.Key, j) }\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := bd.GraphApply(ctx, plan, opts); err != nil {\n\tif strings.Contains(err.Error(), \"has empty target\") {\n\t\t// fill or remove the dep and retry\n\t}\n}","preventionTips":["Construct deps with a helper that requires a target argument","Filter out zero-value dep structs before building the plan","Schema-validate plan files to require dep.target"],"tags":["validation","graph-apply","missing-field"],"backgroundTag":"missing-required-field","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}