{"record":{"id":"4e6c8970fb76c1a7","repo":"gastownhall/beads","slug":"node-q-planned-blocking-dependencies-create-a-pa","errorCode":null,"errorMessage":"node %q: planned blocking dependencies create a path from parent %q to child %q","messagePattern":"node %q: planned blocking dependencies create a path from parent %q to child %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/graph_apply.go","lineNumber":1202,"sourceCode":"\t\tadj[fromID] = append(adj[fromID], toID)\n\t}\n\n\tdepCache := make(map[string][]*types.Dependency)\n\tfor _, node := range plan.Nodes {\n\t\tchildID := keyToID[node.Key]\n\t\tparentID := node.ParentID\n\t\tif parentKey := node.effectiveParentKey(); parentKey != \"\" {\n\t\t\tparentID = keyToID[parentKey]\n\t\t}\n\t\tif childID == \"\" || parentID == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\thasPath, err := graphApplyHasPath(ctx, tx, adj, depCache, parentID, childID, graphApplyReadyPathDependencyType)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif hasPath {\n\t\t\treturn fmt.Errorf(\"node %q: planned blocking dependencies create a path from parent %q to child %q\", node.Key, parentID, childID)\n\t\t}\n\t}\n\treturn nil\n}\n\n// graphApplyHasPath reports whether fromID can reach toID by following the\n// in-memory planned adjacency plus existing store dependencies. followExistingDep\n// selects which existing dep types the walk traverses, letting callers mirror\n// either the early blocking-only preflight or the broader ready-work graph.\nfunc graphApplyHasPath(ctx context.Context, tx storage.Transaction, adj map[string][]string, depCache map[string][]*types.Dependency, fromID, toID string, followExistingDep func(types.DependencyType) bool) (bool, error) {\n\tseen := make(map[string]bool)\n\tvar visit func(string) (bool, error)\n\tvisit = func(id string) (bool, error) {\n\t\tif id == toID {\n\t\t\treturn true, nil\n\t\t}\n\t\tif seen[id] {\n\t\t\treturn false, nil","sourceCodeStart":1184,"sourceCodeEnd":1220,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/graph_apply.go#L1184-L1220","documentation":"Returned by validateGraphApplyPlannedParentBlockingPaths when a parent's planned blocking dependencies would create a ready-path from the parent to its own child — i.e. the parent could become blocked by (or transitively dependent on) its child, violating parent-child ordering invariants.","triggerScenarios":"bd graph apply where node N has parent P, and the planned blocking edges among N/P create a directed path from P to child C along ready-path-relevant dependency types.","commonSituations":"Adding a blocking dep from a parent to an issue that (transitively) blocks back into the parent's subtree; restructuring hierarchies while stale blocking edges exist between parent and child subtrees.","solutions":["Remove or reverse the planned blocking edge that connects the parent's subtree to the child","Detach or re-parent the child before applying the blocking edges","Inspect existing deps on parent and child with bd dep list to find the offending link"],"exampleFix":"// before: parent P planned to block issue X, but X (transitively) blocks child C of P\n{\"nodes\":[{\"key\":\"bd-parent\"}],\"edges\":[{\"from\":\"bd-parent\",\"to\":\"bd-x\"}]}\n// after: block from the child side or remove the parent->X edge\n{\"edges\":[{\"from\":\"bd-x\",\"to\":\"bd-parent\"}]}","handlingStrategy":"validation","validationCode":"// reject blocking edges that cross parent->child subtrees\nfor _, e := range plan.Edges {\n  if isAncestorOrDescendant(tree, e.From, e.To) && blocksReadyPath(e) {\n    return fmt.Errorf(\"edge %s->%s crosses parent/child boundary\", e.From, e.To)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never add blocking deps between a parent and issues inside its own subtree","Re-parent issues before restructuring their dependencies","Model parent-child ordering via hierarchy, not blocking edges"],"tags":["go","hierarchy","dependency-cycle","graph-apply"],"backgroundTag":"dependency-cycle-detected","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}