{"record":{"id":"3b4a910f9ad6a03a","repo":"gastownhall/beads","slug":"edge-s-s-w","errorCode":null,"errorMessage":"edge %s->%s: %w","messagePattern":"edge (.+?)->(.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/graph_apply.go","lineNumber":1052,"sourceCode":"\t\t\tfor i, edge := range plan.Edges {\n\t\t\t\tfromID := resolveEdgeRef(edge.FromKey, edge.FromID, keyToID)\n\t\t\t\ttoID := resolveEdgeRef(edge.ToKey, edge.ToID, keyToID)\n\t\t\t\tdepType := graphApplyDependencyType(edge.Type)\n\t\t\t\tif (depType == types.DepParentChild) != parentPhase {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif parentDepPairs[graphApplyDepPairKey(fromID, toID)] {\n\t\t\t\t\tif depType == types.DepParentChild {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\treturn fmt.Errorf(\"edge %d %s->%s duplicates a parent-child relationship with dependency type %q\", i, fromID, toID, depType)\n\t\t\t\t}\n\t\t\t\tif parentDepPairs[graphApplyDepPairKey(toID, fromID)] && graphApplyCycleRelevantDependencyType(depType) {\n\t\t\t\t\treturn fmt.Errorf(\"edge %d %s->%s creates a blocking reverse of a parent-child relationship\", i, fromID, toID)\n\t\t\t\t}\n\t\t\t\tdep, err := types.NewGraphEdgeDependency(fromID, toID, depType, edge.Gate, edge.SpawnerKey, edge.SpawnerID, edge.ThreadID, keyToID)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"edge %s->%s: %w\", fromID, toID, err)\n\t\t\t\t}\n\t\t\t\tif err := tx.AddDependencyWithOptions(ctx, dep, actor, storage.DependencyAddOptions{}); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"adding edge %s->%s: %w\", fromID, toID, err)\n\t\t\t\t}\n\t\t\t\tif graphApplySchedulingDependencyType(depType) {\n\t\t\t\t\tnewSchedulingEdges = append(newSchedulingEdges, [2]string{fromID, toID})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add per-node inline dependencies in stable order for this phase.\n\t\t\tfor i, node := range plan.Nodes {\n\t\t\t\tfor _, dep := range node.Deps {\n\t\t\t\t\tdepType := types.DependencyType(dep.Type)\n\t\t\t\t\tif depType == \"\" {\n\t\t\t\t\t\tdepType = types.DepBlocks\n\t\t\t\t\t}\n\t\t\t\t\tif (depType == types.DepParentChild) != parentPhase {\n\t\t\t\t\t\tcontinue","sourceCodeStart":1034,"sourceCodeEnd":1070,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/graph_apply.go#L1034-L1070","documentation":"This wraps an error returned by types.NewGraphEdgeDependency while constructing the Dependency record for a plan edge. Construction validates that edge endpoints resolve to real issue IDs (via keyToID) and that gate/spawner/thread metadata is consistent; a failure here means the edge references an unknown node key or has invalid attributes, so the apply transaction stops.","triggerScenarios":"plan.Edges contains fromKey/toKey values not present in keyToID (nodes not created in this plan nor existing in the DB), or invalid gate/spawner references passed to NewGraphEdgeDependency.","commonSituations":"Typos in edge endpoint keys in graph JSON, referencing an external issue key that was never imported, or spawner/gate metadata pointing at nodes not in the plan.","solutions":["Check that both fromKey/toKey exist in the plan's nodes or as existing issue keys in the database","Fix typos in edge endpoint keys in the graph JSON","Remove or correct gate/spawner/thread fields that reference unknown nodes","Run bd doctor / db integrity checks if keys appear valid but don't resolve"],"exampleFix":"// before\n{\"from\":\"tsk-1\",\"to\":\"task-1\",\"type\":\"blocks\"} // typo: tsk-1\n// after\n{\"from\":\"task-1\",\"to\":\"task-2\",\"type\":\"blocks\"}","handlingStrategy":"validation","validationCode":"for _, e := range plan.Edges {\n  if keys[e.FromKey] == nil && !existsInDB(e.FromKey) { return fmt.Errorf(\"unknown edge endpoint %s\", e.FromKey) }\n  if keys[e.ToKey] == nil && !existsInDB(e.ToKey) { return fmt.Errorf(\"unknown edge endpoint %s\", e.ToKey) }\n}","typeGuard":"func endpointsResolve(e Edge, keyToID map[string]string) bool {\n  return keyToID[e.FromKey] != \"\" && keyToID[e.ToKey] != \"\"\n}","tryCatchPattern":"if err := bd.GraphApply(ctx, plan); err != nil && strings.Contains(err.Error(), \"edge \") {\n  return fmt.Errorf(\"plan has unresolved edge endpoints: %w\", err)\n}","preventionTips":["Lint all edge keys against the plan's node keys before applying","Avoid hand-editing generated graph JSON; regenerate instead","Keep gate/spawner references pointing at nodes present in the plan"],"tags":["beads","graph-apply","edge-validation","unresolved-reference"],"backgroundTag":"unresolved-edge-reference","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}