{"record":{"id":"ce826edf7093b43e","repo":"gastownhall/beads","slug":"dep-target-q-not-found","errorCode":null,"errorMessage":"dep target %q not found","messagePattern":"dep target %q not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/types/types.go","lineNumber":1455,"sourceCode":"\treturn dep, nil\n}\n\n// NewGraphNodeDependency builds the dependency record for a graph-plan node's\n// inline dep, shared by the embedded and domain apply paths so their\n// resolution semantics cannot drift: an empty type defaults to blocks, and\n// the target resolves as a plan-local key first, then as a literal issue ID.\n// Waits-for deps carry gate metadata like waits-for edges (all-children\n// default, no explicit spawner).\nfunc NewGraphNodeDependency(issueID string, depType DependencyType, target string, keyToID map[string]string) (*Dependency, error) {\n\tif depType == \"\" {\n\t\tdepType = DepBlocks\n\t}\n\ttargetID := keyToID[target]\n\tif targetID == \"\" {\n\t\ttargetID = target\n\t}\n\tif targetID == \"\" {\n\t\treturn nil, fmt.Errorf(\"dep target %q not found\", target)\n\t}\n\treturn NewGraphEdgeDependency(issueID, targetID, depType, \"\", \"\", \"\", \"\", nil)\n}\n\n// MergeMetadataRefs merges resolved metadata_refs into an issue's existing\n// metadata JSON: each refs entry maps a metadata key to a plan-local node\n// key, which is replaced with its minted ID from keyToID. Shared by the\n// embedded and domain graph-apply paths.\nfunc MergeMetadataRefs(existing json.RawMessage, refs map[string]string, keyToID map[string]string) (json.RawMessage, error) {\n\tmerged := make(map[string]json.RawMessage, len(refs))\n\tif len(existing) > 0 {\n\t\tif err := json.Unmarshal(existing, &merged); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"re-parsing metadata: %w\", err)\n\t\t}\n\t}\n\tfor metaKey, refKey := range refs {\n\t\tresolvedID, ok := keyToID[refKey]\n\t\tif !ok {","sourceCodeStart":1437,"sourceCodeEnd":1473,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/types/types.go#L1437-L1473","documentation":"NewGraphNodeDependency resolves a graph-plan node's inline dependency target: first as a plan-local key via keyToID, then as a literal issue ID. If the target is neither a known key nor a non-empty ID (i.e. resolves to the empty string), the dependency cannot be built and this error is returned.","triggerScenarios":"Calling NewGraphNodeDependency with target=\"\" (and target not present in keyToID), so both the keyToID lookup and the literal fallback yield \"\".","commonSituations":"A graph plan YAML/JSON node declares a dep with an empty target field, or code that strips/normalizes the target reduces it to empty before the call.","solutions":["Set a non-empty target on the plan node's dep (a valid node key or issue ID)","Validate the plan before applying: reject nodes whose deps have empty targets","Ensure keyToID is populated before resolution if the target is meant to be a plan-local key"],"exampleFix":"// before\n\"deps\": [{\"target\": \"\"}]  // empty target\n// after\n\"deps\": [{\"target\": \"bd-a3f8e9\"}]  // or a plan-local node key","handlingStrategy":"validation","validationCode":"func validateDepTarget(target string, keyToID map[string]string) error {\n\tif target == \"\" && keyToID[target] == \"\" {\n\t\treturn fmt.Errorf(\"dep target must be a plan node key or issue ID, got empty string\")\n\t}\n\treturn nil\n}","typeGuard":"func depTargetResolvable(target string, keyToID map[string]string) bool {\n\treturn target != \"\" \n}","tryCatchPattern":"dep, err := types.NewGraphNodeDependency(issueID, depType, target, keyToID)\nif err != nil {\n\tif strings.Contains(err.Error(), \"dep target\") && strings.Contains(err.Error(), \"not found\") {\n\t\treturn fmt.Errorf(\"plan validation: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Validate plans before apply: every dep must have a non-empty target","Keep keyToID populated from the full node set before resolving deps","Normalize target fields without dropping empty-string checks"],"tags":["go","graph-plan","dependency","target-resolution"],"backgroundTag":"unresolved-plan-node-key","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}