gastownhall/beads · error

duplicate node key %q

Error message

duplicate node key %q

What it means

During `bd graph apply` plan validation, each node's key is checked against a set of already-seen keys. If two nodes in plan.nodes share the same key, the apply is rejected with this error. Keys must be unique because they are the identity used for parent/dep/metadata references.

Source

Thrown at cmd/bd/graph_apply.go:536

			return fmt.Errorf("explicit id %q (node %q) already exists; graph create will not overwrite an existing issue — drop the id to mint a new one, or update the existing issue instead", node.ID, node.Key)
		}
	}
	return nil
}

func validateGraphApplyPlan(plan *GraphApplyPlan, customTypes, customStatuses []string, opts GraphApplyOptions) error {
	if len(plan.Nodes) == 0 {
		return fmt.Errorf("plan has no nodes")
	}

	seenKeys := make(map[string]bool, len(plan.Nodes))
	seenIDs := make(map[string]bool)
	for i, node := range plan.Nodes {
		if node.Key == "" {
			return fmt.Errorf("node %d has empty key", i)
		}
		if seenKeys[node.Key] {
			return fmt.Errorf("duplicate node key %q", node.Key)
		}
		seenKeys[node.Key] = true
		if node.Title == "" {
			return fmt.Errorf("node %q has empty title", node.Key)
		}
		if err := validateGraphApplyNodeFields(node, customTypes, customStatuses, opts); err != nil {
			return err
		}
		if node.ID != "" {
			if seenIDs[node.ID] {
				return fmt.Errorf("duplicate explicit id %q (node %q)", node.ID, node.Key)
			}
			seenIDs[node.ID] = true
		}
		// Validate MetadataRefs point to known keys.
		for metaKey, refKey := range node.MetadataRefs {
			if !seenKeys[refKey] {
				found := false

View on GitHub (pinned to 71377f2769)

Solutions

  1. Find the duplicated key in the plan file and give one of the nodes a unique key
  2. Update all parent_key, deps[].target, metadata_refs, and edge from/to references that pointed at the renamed key
  3. Regenerate the plan programmatically ensuring key uniqueness before applying

Example fix

// before
"nodes": [{"key": "auth"}, {"key": "auth"}]
// after
"nodes": [{"key": "auth-login"}, {"key": "auth-logout"}]
Defensive patterns

Strategy: validation

Validate before calling

keys := map[string]bool{}
for _, n := range plan.Nodes {
	if keys[n.Key] { return fmt.Errorf("duplicate node key %q", n.Key) }
	keys[n.Key] = true
}

Try / catch

if err := bd.GraphApply(ctx, plan, opts); err != nil {
	if strings.HasPrefix(err.Error(), "duplicate node key") {
		// fix plan and retry
	}
}

Prevention

When it happens

Trigger: Calling `bd graph apply` with a plan whose nodes array contains two entries with identical `key` values.

Common situations: Hand-written or template-generated plan files where a node was copy-pasted without renaming its key; script loops that append nodes with a constant key; merging plans from different sources that happen to use the same keys.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/408ea2d70ed9d8ce. Report an issue: GitHub.