gastownhall/beads · error

issue not found: %s

Error message

issue not found: %s

What it means

After GetIssue returns no error, runUnrelate checks whether the first issue came back nil; if so it reports 'issue not found: <id1>'. Beads' storage returns (nil, nil) for a nonexistent issue, so this is the explicit missing-record path rather than a storage failure. bd unrelate requires both endpoints of the relates-to link to exist.

Source

Thrown at cmd/bd/relate.go:182

	}
	id2, err = utils.ResolvePartialID(ctx, store, args[1])
	if err != nil {
		return fmt.Errorf("failed to resolve %s: %w", args[1], err)
	}

	// Get both issues
	var issue1, issue2 *types.Issue
	issue1, err = store.GetIssue(ctx, id1)
	if err != nil {
		return fmt.Errorf("failed to get issue %s: %w", id1, err)
	}
	issue2, err = store.GetIssue(ctx, id2)
	if err != nil {
		return fmt.Errorf("failed to get issue %s: %w", id2, err)
	}

	if issue1 == nil {
		return fmt.Errorf("issue not found: %s", id1)
	}
	if issue2 == nil {
		return fmt.Errorf("issue not found: %s", id2)
	}

	// Remove relates-to dependency in both directions
	// Per Decision 004, relates-to links are now stored in dependencies table.
	// bd unrelate is an explicit dependency verb, so it records history
	// (EmitEvent) like bd dep remove; only structural teardown stays silent.
	// Remove id1 -> id2
	if err := store.RemoveDependencyWithOptions(ctx, id1, id2, actor, storage.DependencyRemoveOptions{EmitEvent: true}); err != nil {
		return fmt.Errorf("failed to remove relates-to %s -> %s: %w", id1, id2, err)
	}
	// Remove id2 -> id1 (bidirectional)
	if err := store.RemoveDependencyWithOptions(ctx, id2, id1, actor, storage.DependencyRemoveOptions{EmitEvent: true}); err != nil {
		return fmt.Errorf("failed to remove relates-to %s -> %s: %w", id2, id1, err)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run `bd show <id1>` (or `bd list`) to confirm the ID exists locally; correct typos in the ID.
  2. If the ID lives in another repository, cd into the right repo before running unrelate.
  3. If the issue should exist, sync first: `bd dolt pull` to fetch remote deletions/creations, then re-check.
  4. If the issue was genuinely deleted, the link is already gone — nothing to unrelate; verify with `bd dep <id2>` and proceed without the command.
  5. Use `bd ready`/`bd list` to find the correct current ID rather than relying on memory or old shell history.

Example fix

// before
$ bd unrelate bd-12 bd-7   # bd-12 never existed (typo for bd-112)
issue not found: bd-12
// after
$ bd unrelate bd-112 bd-7
Defensive patterns

Strategy: validation

Validate before calling

func requireIssue(ctx context.Context, store storage.Store, id string) error {
	issue, err := store.GetIssue(ctx, id)
	if err != nil {
		return err
	}
	if issue == nil {
		return fmt.Errorf("issue %s does not exist locally; run 'bd list' or 'bd dolt pull' first", id)
	}
	return nil
}

Type guard

func issueExists(ctx context.Context, store storage.Store, id string) bool {
	issue, err := store.GetIssue(ctx, id)
	return err == nil && issue != nil
}

Prevention

When it happens

Trigger: `bd unrelate <id1> <id2>` where id1 does not exist in the store: mistyped or stale issue ID, issue deleted earlier, wrong repository/directory (the ID exists in another .beads database), or an ID from an unsynced remote.

Common situations: Copy-pasting IDs from another project's output; the issue was closed and garbage-collected or deleted on another machine and synced away; typos like bd-12 vs bd-112; running in a fresh clone before `bd dolt pull` fetched the issues.

Related errors


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