gastownhall/beads · error

failed to update gate with discovered run ID: %w

Error message

failed to update gate with discovered run ID: %w

What it means

Wraps a failure from IssueUseCase().UpdateIssue when applying a discovered workflow run ID to a gate issue via the await_id field. The discovery loop collected a run ID from GitHub Actions but the storage write to attach it to the gate failed. The error is captured per-gate in awaitErrs so other gates continue processing.

Source

Thrown at cmd/bd/gate_proxied_server.go:112

		printNoOpenGates(gateTypeFilter)
		return nil
	}
	results := evaluateGates(ctx, filteredGates, time.Now(), proxiedFreshReadGetter{}, persistAwaitID)

	if dryRun {
		resolved, escalated, errCount := applyGateCheckResults(results, true, escalateFlag, nil)
		return printGateCheckSummary(len(results), resolved, escalated, errCount, dryRun)
	}

	applied, err := uow.RunTxResult(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (gateCheckApply, string, error) {
		out := gateCheckApply{
			closeErrs: map[string]error{},
			awaitErrs: map[string]error{},
		}

		for gateID, runID := range discovered {
			if err := uw.IssueUseCase().UpdateIssue(ctx, gateID, map[string]any{"await_id": runID}, actor); err != nil {
				out.awaitErrs[gateID] = fmt.Errorf("failed to update gate with discovered run ID: %w", err)
				continue
			}
			if after, getErr := uw.IssueUseCase().GetIssue(ctx, gateID); getErr == nil && after != nil {
				out.updated = append(out.updated, after)
			}
		}

		for _, r := range results {
			if r.err != nil || !r.resolved {
				continue
			}
			if _, awaitFailed := out.awaitErrs[r.gate.ID]; awaitFailed {
				continue
			}
			before, _ := uw.IssueUseCase().GetIssue(ctx, r.gate.ID)
			if before != nil && before.Status == types.StatusClosed {
				continue
			}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the gate issue still exists (`bd show <gateID>`) and re-run the discovery/apply step
  2. Check storage health (`bd doctor`) and retry — transient Dolt/connection failures resolve on retry
  3. Confirm no concurrent process holds a conflicting write on the gate; re-run after the other process finishes
  4. Inspect the wrapped inner error (%w) for the exact storage failure and address it directly

Example fix

// before: gate may no longer exist when applying run ID
if err := uw.IssueUseCase().UpdateIssue(ctx, gateID, map[string]any{"await_id": runID}, actor); err != nil {
    out.awaitErrs[gateID] = fmt.Errorf("failed to update gate with discovered run ID: %w", err)
    continue
}
// after: pre-check existence and log the inner cause
if _, err := uw.IssueUseCase().GetIssue(ctx, gateID); err != nil {
    out.awaitErrs[gateID] = fmt.Errorf("gate %s disappeared before await_id update: %w", gateID, err)
    continue
}
if err := uw.IssueUseCase().UpdateIssue(ctx, gateID, map[string]any{"await_id": runID}, actor); err != nil {
    out.awaitErrs[gateID] = fmt.Errorf("failed to update gate with discovered run ID: %w", err)
    continue
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := bdClient.Show(ctx, gateID); err != nil {
    return fmt.Errorf("skip apply: gate %s no longer exists: %w", gateID, err)
}

Type guard

func gateStillExists(ctx context.Context, uc *IssueUseCase, gateID string) bool {
    issue, err := uc.GetIssue(ctx, gateID)
    return err == nil && issue != nil
}

Try / catch

err := applyDiscoveredRuns(ctx, discovered)
if err != nil {
    for gateID, awaitErr := range awaitErrs {
        log.Printf("gate %s await_id update failed: %v — verify gate exists and storage is healthy, then re-run discover", gateID, awaitErr)
    }
}

Prevention

When it happens

Trigger: UpdateIssue(ctx, gateID, {"await_id": runID}) returns an error during gate discovery apply — e.g. the gate issue was deleted after discovery, the Dolt/storage backend is unreachable, a write conflict or validation rejection occurred on the await_id update.

Common situations: Gate issue deleted or closed by another agent between discovery and apply; Dolt server restarted or connection dropped mid-transaction; concurrent update to the same gate causing a conflict; storage permission problem.

Related errors


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