gastownhall/beads · error

%s is not a proto (missing '%s' label)

Error message

%s is not a proto (missing '%s' label)

What it means

bd mol pour requires the target issue to be a proto — an issue carrying the molecule label (MoleculeLabel). After loading the issue, isProto checks the label; if missing, pour refuses with '<id> is not a proto (missing '<label>' label)'. This prevents pouring an ordinary issue as if it were a reusable template.

Source

Thrown at cmd/bd/mol_proxied_server.go:68

	}

	res, err := uow.RunTxResult(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (pourProxiedResult, string, error) {
		w := newUOWMolWriter(uw)

		subgraph := formulaSubgraph
		protoID := formulaProtoID
		if subgraph == nil {
			resolvedID, err := utils.ResolvePartialID(ctx, w, in.protoArg)
			if err != nil {
				return pourProxiedResult{}, "", fmt.Errorf("%s not found as formula or proto ID", in.protoArg)
			}
			protoID = resolvedID
			protoIssue, err := w.GetIssue(ctx, protoID)
			if err != nil {
				return pourProxiedResult{}, "", fmt.Errorf("loading proto %s: %w", protoID, err)
			}
			if !isProto(protoIssue) {
				return pourProxiedResult{}, "", fmt.Errorf("%s is not a proto (missing '%s' label)", protoID, MoleculeLabel)
			}
			subgraph, err = loadTemplateSubgraph(ctx, w, protoID)
			if err != nil {
				return pourProxiedResult{}, "", fmt.Errorf("loading proto: %w", err)
			}
		}

		type attachmentInfo struct {
			id       string
			issue    *types.Issue
			subgraph *TemplateSubgraph
		}
		var attachments []attachmentInfo
		for _, attachArg := range in.attachArgs {
			attachID, err := utils.ResolvePartialID(ctx, w, attachArg)
			if err != nil {
				return pourProxiedResult{}, "", fmt.Errorf("resolving attachment ID %s: %w", attachArg, err)
			}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use the molecule ROOT id, not a child step: bd show <id> and check the parent-child dependencies
  2. Verify the label: bd show <id> should list the molecule label; re-add it if stripped (bd update <id> --add-label <MoleculeLabel> or the equivalent label command)
  3. If the molecule was promoted to regular issues, re-create a proto with bd mol create / pour from the original formula
  4. Confirm with bd mol list which IDs are actual protos

Example fix

// before: pouring a child
$ bd mol pour bd-456
Error: bd-456 is not a proto (missing 'molecule' label)
// after: use the molecule root
$ bd mol pour bd-100
Defensive patterns

Strategy: validation

Validate before calling

// confirm the target carries the molecule label before pouring
issue, err := reader.GetIssue(ctx, protoID)
if err == nil && !hasLabel(issue.Labels, MoleculeLabel) {
	return fmt.Errorf("%s is not a molecule proto", protoID)
}

Type guard

func isProtoIssue(issue *types.Issue) bool {
	return issue != nil && slices.Contains(issue.Labels, MoleculeLabel)
}

Try / catch

err := pourCmd(protoID)
if err != nil && strings.Contains(err.Error(), "is not a proto") {
	return fmt.Errorf("%s is not a proto; pick a root from `bd mol list`", protoID)
}

Prevention

When it happens

Trigger: Running `bd mol pour <id>` where <id> resolves to a regular issue (no molecule label): passing a child step ID instead of the molecule root ID, or an issue whose molecule label was removed (e.g. after promotion/hydration of a molecule into regular issues).

Common situations: Copy-pasting a step ID like bd-456 (a child) instead of the parent molecule ID; labels stripped by an import/export round-trip or a sync conflict; trying to pour a previously-poured instance that no longer carries the proto label.

Related errors


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