gastownhall/beads · error

bonding: %w

Error message

bonding: %w

What it means

Wrapped error from the molecule bonding step inside the `bd mol bond` proxied-server transaction. After both issues load and the correct bonding path is chosen (proto+proto, proto+mol, or mol+mol via bondMolMolInto), executing the bond failed; the error is surfaced through HandleErrorRespectJSON and the transaction rolls back.

Source

Thrown at cmd/bd/mol_proxied_server.go:431

		issueA := subgraphA.Root
		issueB := subgraphB.Root
		aIsProto := issueA.IsTemplate || cookedA
		bIsProto := issueB.IsTemplate || cookedB

		var result *BondResult
		switch {
		case aIsProto && bIsProto:
			result, err = bondProtoProtoInto(ctx, w, issueA, issueB, in.bondType, in.customTitle, actor)
		case aIsProto && !bIsProto:
			result, err = bondProtoMolAttachInto(ctx, w, subgraphA, issueA, issueB, in.bondType, in.vars, in.childRef, actor, in.ephemeral, in.pour)
		case !aIsProto && bIsProto:
			result, err = bondProtoMolAttachInto(ctx, w, subgraphB, issueB, issueA, in.bondType, in.vars, in.childRef, actor, in.ephemeral, in.pour)
		default:
			result, err = bondMolMolInto(ctx, w, issueA, issueB, in.bondType, actor)
		}
		if err != nil {
			return bondTxResult{}, "", fmt.Errorf("bonding: %w", err)
		}
		return bondTxResult{result: result, idA: issueA.ID, idB: issueB.ID},
			fmt.Sprintf("bd: mol bond %s %s", issueA.ID, issueB.ID), nil
	})
	if err != nil {
		return HandleErrorRespectJSON("%v", err)
	}

	return renderMolBondResult(res.result, res.idA, res.idB, in.ephemeral, in.pour)
}

func runMolSquashProxiedServer(ctx context.Context, in molSquashInput) error {
	CheckReadonly("mol squash")

	if uowProvider == nil {
		return HandleErrorRespectJSON("proxied-server UOW provider not initialized")
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the inner error to determine whether it is a cycle, duplicate bond, or storage failure
  2. Run `bd show <idA>` / `bd show <idB>` to check existing dependencies before re-bonding
  3. Use a valid bond type flag and ensure neither ID is the other's ancestor (cycle)
  4. If a proto attach, supply any --var values its template requires

Example fix

// before
bd mol bond bd-100 bd-200 --bond-type blocks   // fails: cycle: bd-100 already blocks bd-200 indirectly
// after
bd show bd-100                                 // inspect deps, remove conflicting edge, then bond
bd mol bond bd-100 bd-200 --bond-type related
Defensive patterns

Strategy: validation

Validate before calling

// Check existing dependencies before bonding
bd show <idA>
bd show <idB>
// Ensure neither is an ancestor of the other (would create a cycle)

Type guard

func bondFailedBetween(err error) (a, b string, ok bool) {
    // bondTxResult carries idA/idB; parse "mol bond <a> <b>" from context or inspect deps first
    return "", "", err != nil
}

Try / catch

if err := runMolBondProxiedServer(ctx, in); err != nil {
    if strings.Contains(err.Error(), "cycle") {
        return fmt.Errorf("choose a different bond type or restructure the molecule graph")
    }
    return err
}

Prevention

When it happens

Trigger: Run `bd mol bond <idA> <idB>` where the selected bond function (bondProtoMolAttachInto or bondMolMolInto) fails: one issue is already bonded, bond type invalid, dependency cycle would be created, or storage write failure.

Common situations: Trying to bond a molecule to itself or to an issue already sharing that dependency edge; invalid --bond-type; variable requirements of the attached proto unmet; concurrent modification of either molecule.

Related errors


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