gastownhall/beads · error
applyGraph: node %q: defer assignee: %w
Error message
applyGraph: node %q: defer assignee: %w
What it means
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.
Source
Thrown at internal/storage/domain/issue.go:1304
newSchedulingEdges = append(newSchedulingEdges, [2]string{dep.IssueID, dep.DependsOnID})
}
}
}
}
if cyclePath, err := u.depRepo.CycleThroughEdges(ctx, newSchedulingEdges); err != nil {
return GraphApplyResult{}, fmt.Errorf("applyGraph: final cycle check: %w", err)
} else if cyclePath != "" {
return GraphApplyResult{}, fmt.Errorf("applyGraph: dependency cycle would be created: %s", cyclePath)
}
// Pass 5 — apply deferred assignees.
for i, assignee := range pendingAssignees {
if assignee == "" {
continue
}
id := keyToID[plan.Nodes[i].Key]
if err := u.issueRepo.Update(ctx, id, map[string]any{"assignee": assignee}, actor, IssueTableOpts{UseWispsTable: useWisp}); err != nil {
return GraphApplyResult{}, fmt.Errorf("applyGraph: node %q: defer assignee: %w", plan.Nodes[i].Key, err)
}
}
return GraphApplyResult{IDs: keyToID}, nil
}
// graphParentDepPairs encodes the (childID, parentID) parent-child pairs
// implied by the plan's node ParentKey/ParentID fields. Used by applyGraph
// to dedup explicit edges against implicit parent-child relationships and
// to seed the in-memory adjacency for live cycle detection.
func graphParentDepPairs(nodes []GraphNode, keyToID map[string]string) map[string]bool {
pairs := make(map[string]bool, len(nodes))
for _, n := range nodes {
parentID := n.ParentID
if n.ParentKey != "" {
parentID = keyToID[n.ParentKey]
}
childID := keyToID[n.Key]View on GitHub (pinned to 71377f2769)
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.
Example fix
// before: apply fails only on assignee write bd graph apply plan.yaml // after: set assignee directly on the created issue bd update bd-42 --assignee alice
Defensive patterns
Strategy: validation
Validate before calling
// Validate assignees are set only on nodes that will exist in the right table
for i, a := range plan.Nodes[i].Assignee...; {
if a != "" && tableMismatch(plan.Nodes[i], useWisp) {
return fmt.Errorf("node %s: assignee with mismatched table", plan.Nodes[i].Key)
}
} Try / catch
if err := bd.GraphApply(ctx, plan); err != nil {
if strings.Contains(err.Error(), "defer assignee") {
// nodes/edges likely created; set assignees manually
for _, n := range plan.Nodes {
_ = exec("bd", "update", n.Key, "--assignee", n.Assignee)
}
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- %w: invalid forced assignee transfer
- %w: issue %s is assigned to %q
- no store is open for this workspace
- not found
- db: ChildCounterSQLRepository.NextChildID: parentID must not
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4873bc3fd5945c55.
Report an issue: GitHub.