gastownhall/beads · error

linking proto A

Error message

linking proto A: %w

What it means

After the compound is created, bondProtoProtoInto links proto A to it with a parent-child dependency; if w.AddDependency fails the bond aborts with this error naming proto A.

Solutions

  1. Check the wrapped inner error for the driver cause.
  2. Close competing bd processes and retry the bond; note the compound may already exist from the failed attempt — check for it before re-running to avoid duplicates.
  3. Verify the .beads storage is writable and healthy (bd doctor), then re-run.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify compound exists and is writable before linking deps
if _, err := w.GetIssue(ctx, compoundID); err != nil {
    return fmt.Errorf("compound %s not retrievable: %w", compoundID, err)
}

Try / catch

if err := bond(ctx, w, a, b, bt, actor); err != nil {
    if strings.Contains(err.Error(), "linking proto A:") {
        // compound was created; look it up before retrying to avoid duplicates
    }
    return err
}

Prevention

When it happens

Trigger: w.AddDependency(ctx, depA, actorName) errors right after compound creation — driver write failure, lock contention, or the compound ID not yet visible to the writer.

Common situations: Database lock from a concurrent bd process mid-bond, or an earlier partial bond leaving inconsistent state the writer rejects.

Related errors


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

Appendix: source

Thrown at cmd/bd/mol_bond.go:350

		Labels:      []string{MoleculeLabel},
		BondedFrom: []types.BondRef{
			{SourceID: protoA.ID, BondType: bondType, BondPoint: ""},
			{SourceID: protoB.ID, BondType: bondType, BondPoint: ""},
		},
	}
	if err := w.CreateIssue(ctx, compound, actorName); err != nil {
		return nil, fmt.Errorf("creating compound: %w", err)
	}
	compoundID := compound.ID

	// Add parent-child dependencies from compound to both proto roots
	depA := &types.Dependency{
		IssueID:     protoA.ID,
		DependsOnID: compoundID,
		Type:        types.DepParentChild,
	}
	if err := w.AddDependency(ctx, depA, actorName); err != nil {
		return nil, fmt.Errorf("linking proto A: %w", err)
	}

	depB := &types.Dependency{
		IssueID:     protoB.ID,
		DependsOnID: compoundID,
		Type:        types.DepParentChild,
	}
	if err := w.AddDependency(ctx, depB, actorName); err != nil {
		return nil, fmt.Errorf("linking proto B: %w", err)
	}

	// For sequential/conditional bonding, add blocking dependency: B blocks on A
	// Sequential: B runs after A completes (any outcome)
	// Conditional: B runs only if A fails
	if bondType == types.BondTypeSequential || bondType == types.BondTypeConditional {
		depType := types.DepBlocks
		if bondType == types.BondTypeConditional {
			depType = types.DepConditionalBlocks

View on GitHub (pinned to 71377f2769)