gastownhall/beads · error

cannot mark an issue as superseded by itself

Error message

cannot mark an issue as superseded by itself

What it means

Self-supersede guard in runSupersede: after resolution, oldID equals newID, so an issue cannot be superseded by itself. Raised before any store mutation, preventing a degenerate supersede relationship and possible lifecycle loops.

Source

Thrown at cmd/bd/duplicate.go:160

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

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

	if oldID == newID {
		return fmt.Errorf("cannot mark an issue as superseded by itself")
	}

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

	// Add a "supersedes" dependency edge (old → new)
	dep := &types.Dependency{
		IssueID:     oldID,
		DependsOnID: newID,
		Type:        types.DepSupersedes,
	}
	if err := store.AddDependency(ctx, dep, actor); err != nil {
		return fmt.Errorf("failed to add supersede link: %w", err)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Create or identify a genuinely different replacement issue and pass its ID
  2. Use sufficiently long prefixes so both arguments resolve to distinct issues
  3. If no replacement exists, don't run supersede — close the old issue instead

Example fix

// before
$ bd supersede bd-42 --superseded-with bd-4
Error: cannot mark an issue as superseded by itself
// after
$ bd supersede bd-42 --superseded-with bd-101
Defensive patterns

Strategy: validation

Validate before calling

if oldID == newID {
    return errors.New("old and replacement issues must differ")
}

Prevention

When it happens

Trigger: `bd supersede bd-42 --superseded-with bd-42`, or two different prefixes that both resolve to the same issue (e.g. bd-4 and bd-42 when only bd-42 exists).

Common situations: Accidentally passing the same ID twice; short prefixes resolving to the same issue; scripted commands reusing one variable for both arguments.

Related errors


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