gastownhall/beads · error

cannot mark an issue as duplicate of itself

Error message

cannot mark an issue as duplicate of itself

What it means

A self-duplicate guard in runDuplicate: after resolving both IDs, the duplicate and canonical IDs are identical, so marking it as a duplicate of itself is rejected. This is a pure validation error raised before any store mutation, protecting the dependency graph from a degenerate 'duplicates' edge.

Source

Thrown at cmd/bd/duplicate.go:90

	ctx := getRootContext()
	store := getStore()
	actor := getActor()

	// Resolve partial IDs
	var duplicateID, canonicalID string
	var err error
	duplicateID, err = utils.ResolvePartialID(ctx, store, args[0])
	if err != nil {
		return fmt.Errorf("failed to resolve %s: %w", args[0], err)
	}
	canonicalID, err = utils.ResolvePartialID(ctx, store, duplicateOf)
	if err != nil {
		return fmt.Errorf("failed to resolve %s: %w", duplicateOf, err)
	}

	if duplicateID == canonicalID {
		return fmt.Errorf("cannot mark an issue as duplicate of itself")
	}

	// Verify canonical issue exists
	var canonical *types.Issue
	canonical, err = store.GetIssue(ctx, canonicalID)
	if err != nil || canonical == nil {
		return fmt.Errorf("canonical issue not found: %s", canonicalID)
	}

	// Add a "duplicates" dependency edge (duplicate → canonical)
	dep := &types.Dependency{
		IssueID:     duplicateID,
		DependsOnID: canonicalID,
		Type:        types.DepDuplicates,
	}
	if err := store.AddDependency(ctx, dep, actor); err != nil {
		return fmt.Errorf("failed to add duplicate link: %w", err)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Pass a different canonical issue in --duplicate-of than the issue being marked duplicate
  2. Re-read the command semantics: bd duplicate <duplicate-id> --duplicate-of <canonical-id>
  3. If the issue is genuinely not a duplicate, skip the command entirely

Example fix

// before
$ bd duplicate bd-42 --duplicate-of bd-42
Error: cannot mark an issue as duplicate of itself
// after
$ bd duplicate bd-42 --duplicate-of bd-17
Defensive patterns

Strategy: validation

Validate before calling

if dupID == canID {
    return errors.New("duplicate and canonical must be different issues")
}

Prevention

When it happens

Trigger: `bd duplicate bd-42 --duplicate-of bd-42` or using the same prefix for both the positional argument and --duplicate-of where both resolve to the same issue.

Common situations: Copy-pasting the same ID into both arguments; scripting that interpolates the same variable twice; misunderstanding the command as 're-issue' rather than 'mark X as duplicate of Y'.

Related errors


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