{"record":{"id":"4873bc3fd5945c55","repo":"gastownhall/beads","slug":"applygraph-node-q-defer-assignee-w","errorCode":null,"errorMessage":"applyGraph: node %q: defer assignee: %w","messagePattern":"applyGraph: node %q: defer assignee: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1304,"sourceCode":"\t\t\t\t\tnewSchedulingEdges = append(newSchedulingEdges, [2]string{dep.IssueID, dep.DependsOnID})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif cyclePath, err := u.depRepo.CycleThroughEdges(ctx, newSchedulingEdges); err != nil {\n\t\treturn GraphApplyResult{}, fmt.Errorf(\"applyGraph: final cycle check: %w\", err)\n\t} else if cyclePath != \"\" {\n\t\treturn GraphApplyResult{}, fmt.Errorf(\"applyGraph: dependency cycle would be created: %s\", cyclePath)\n\t}\n\n\t// Pass 5 — apply deferred assignees.\n\tfor i, assignee := range pendingAssignees {\n\t\tif assignee == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tid := keyToID[plan.Nodes[i].Key]\n\t\tif err := u.issueRepo.Update(ctx, id, map[string]any{\"assignee\": assignee}, actor, IssueTableOpts{UseWispsTable: useWisp}); err != nil {\n\t\t\treturn GraphApplyResult{}, fmt.Errorf(\"applyGraph: node %q: defer assignee: %w\", plan.Nodes[i].Key, err)\n\t\t}\n\t}\n\n\treturn GraphApplyResult{IDs: keyToID}, nil\n}\n\n// graphParentDepPairs encodes the (childID, parentID) parent-child pairs\n// implied by the plan's node ParentKey/ParentID fields. Used by applyGraph\n// to dedup explicit edges against implicit parent-child relationships and\n// to seed the in-memory adjacency for live cycle detection.\nfunc graphParentDepPairs(nodes []GraphNode, keyToID map[string]string) map[string]bool {\n\tpairs := make(map[string]bool, len(nodes))\n\tfor _, n := range nodes {\n\t\tparentID := n.ParentID\n\t\tif n.ParentKey != \"\" {\n\t\t\tparentID = keyToID[n.ParentKey]\n\t\t}\n\t\tchildID := keyToID[n.Key]","sourceCodeStart":1286,"sourceCodeEnd":1322,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1286-L1322","documentation":"In the final pass, applyGraph applies deferred assignees via issueRepo.Update; this error wraps a failure updating the assignee field for the node whose key is quoted. The issues and dependencies were already created — only the assignee write failed — so the graph may be partially applied.","triggerScenarios":"issueRepo.Update on {\"assignee\": ...} fails for a node: the issue row was not actually created or is in the wrong table (wisp mismatch), the update violates a constraint, or the storage layer errors out. Also possible if keyToID lookup returned an empty/invalid id for the node key.","commonSituations":"Assignee strings set on wisp nodes while UseWispsTable points at the regular table (or vice versa); DB write failures late in a long apply; plans where a node key silently failed to map to an ID earlier.","solutions":["Read the wrapped error; if it's not-found, the node wasn't created — check earlier passes' errors.","Verify wisp vs regular table consistency for nodes carrying assignees.","Re-run the apply (creation passes should be idempotent) to retry only the assignee update.","Set the assignee manually with bd update <id> --assignee if only this field failed."],"exampleFix":"// before: apply fails only on assignee write\nbd graph apply plan.yaml\n// after: set assignee directly on the created issue\nbd update bd-42 --assignee alice","handlingStrategy":"validation","validationCode":"// Validate assignees are set only on nodes that will exist in the right table\nfor i, a := range plan.Nodes[i].Assignee...; {\n    if a != \"\" && tableMismatch(plan.Nodes[i], useWisp) {\n        return fmt.Errorf(\"node %s: assignee with mismatched table\", plan.Nodes[i].Key)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := bd.GraphApply(ctx, plan); err != nil {\n    if strings.Contains(err.Error(), \"defer assignee\") {\n        // nodes/edges likely created; set assignees manually\n        for _, n := range plan.Nodes {\n            _ = exec(\"bd\", \"update\", n.Key, \"--assignee\", n.Assignee)\n        }\n    }\n    return err\n}","preventionTips":["Keep wisp flags consistent for nodes carrying assignees","Verify node key -> ID mapping succeeded before the assignee pass (check earlier errors)","Set assignees in a separate step if partial-apply recovery matters"],"tags":["go","storage","assignee","partial-apply"],"backgroundTag":"issue-update-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}