gastownhall/beads · error

'%s' is not an epic or molecule (type: %s)

Error message

'%s' is not an epic or molecule (type: %s)

What it means

Error from runSwarmValidateProxiedServer in cmd/bd/swarm_proxied_server.go:63. A guard that rejects arguments resolving to an issue whose IssueType is neither "epic" nor "molecule" — `bd swarm validate` only operates on swarm-capable parents. The actual type is reported in the message.

Source

Thrown at cmd/bd/swarm_proxied_server.go:63

		r := uowMolReader{uw: uw}

		epicID, err := utils.ResolvePartialID(ctx, r, args[0])
		if err != nil {
			return nil, fmt.Errorf("epic '%s' not found: %v", args[0], err)
		}

		epic, err := uw.IssueUseCase().GetIssue(ctx, epicID)
		if gateProxiedNotFound(err) || (err == nil && epic == nil) {
			// Classic reports a nil epic after a successful resolve this way;
			// keep the message for parity.
			return nil, fmt.Errorf("epic '%s' not found", epicID)
		}
		if err != nil {
			return nil, fmt.Errorf("failed to get epic: %v", err)
		}

		if epic.IssueType != types.TypeEpic && epic.IssueType != "molecule" {
			return nil, fmt.Errorf("'%s' is not an epic or molecule (type: %s)", epicID, epic.IssueType)
		}

		analysis, err := analyzeEpicForSwarm(ctx, r, epic)
		if err != nil {
			return nil, fmt.Errorf("failed to analyze epic: %v", err)
		}
		return analysis, nil
	})
	if err != nil {
		return HandleErrorRespectJSON("%v", err)
	}

	if !verbose {
		analysis.Issues = nil
	}

	if jsonOutput {
		if jerr := outputJSON(analysis); jerr != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Identify the parent epic: `bd show <id>` and follow its parent-child dependency, or use `bd dep tree <id>`.
  2. Re-run with the epic or molecule ID: `bd swarm validate <epic-id>`.
  3. If the issue should be an epic, recreate or retype it (type changes may be restricted depending on existing dependencies).
  4. For checking a single task's swarm status, use `bd swarm status <task-id>` instead.

Example fix

// before
bd swarm validate bd-1240   // bd-1240 is a task

// after
bd swarm validate bd-1230   // bd-1230 is the parent epic
Defensive patterns

Strategy: validation

Validate before calling

type=$(bd show "$ID" --json | jq -r '.issue_type'); [ "$type" = epic ] || [ "$type" = molecule ] || echo "$ID is $type, not an epic/molecule"

Type guard

func isSwarmableType(issueType string) bool {
    return issueType == "epic" || issueType == "molecule"
}

Prevention

When it happens

Trigger: `bd swarm validate <id>` where <id> resolves to a plain task, bug, feature, or chore issue rather than an epic or molecule.

Common situations: Passing a child/task ID instead of its parent epic; the issue's type was changed after creation (e.g. via `bd update --type`); confusing molecule membership with epic ownership.

Related errors


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