gastownhall/beads · error

resolving %s: %w

Error message

resolving %s: %w

What it means

Wraps any non-ErrNotFound error from workapi.GetIssueOrWisp while resolving the target issue for a proxied heartbeat. It distinguishes 'the lookup itself failed' from 'the issue does not exist'. The %w keeps the underlying storage/use-case cause.

Source

Thrown at cmd/bd/heartbeat_proxied_server.go:40

// bd-lrgn1): the transaction commits via uow.RunTxEphemeral's SQL-only form,
// so a heartbeat mints exactly ZERO Dolt commits per invocation — the same
// commit discipline as the classic DoltStore.HeartbeatIssue, and deliberately
// nothing here sets commandDidWrite or creates a Dolt commit. The exit code
// is the worker contract (workers call this every ~90s and only check rc):
// 0 = lease refreshed; nonzero = the lease is gone (wrong owner, not
// in_progress, closed, reclaimed) and the worker should stop.
func runHeartbeatProxiedServer(ctx context.Context, id string) error {
	if uowProvider == nil {
		return HandleErrorRespectJSON("proxied-server UOW provider not initialized")
	}

	res, err := uow.RunTxEphemeral(ctx, uowProvider, func(ctx context.Context, uw uow.UnitOfWork) (heartbeatProxiedOutcome, error) {
		issue, _, rerr := workapi.GetIssueOrWisp(ctx, workapi.NewUOWDetailSource(uw), id)
		if errors.Is(rerr, storage.ErrNotFound) {
			return heartbeatProxiedOutcome{}, fmt.Errorf("issue %s not found", id)
		}
		if rerr != nil {
			return heartbeatProxiedOutcome{}, fmt.Errorf("resolving %s: %w", id, rerr)
		}
		// Wisps resolve here too and are refused below: the repo verb
		// classifies them ErrNotClaimable ("is ephemeral"), same as classic.
		if herr := uw.IssueUseCase().Heartbeat(ctx, issue.ID, actor); herr != nil {
			return heartbeatProxiedOutcome{}, fmt.Errorf("heartbeat %s: %w", issue.ID, herr)
		}
		return heartbeatProxiedOutcome{id: issue.ID, title: issue.Title}, nil
	})
	if err != nil {
		return HandleErrorRespectJSON("%v", err)
	}

	SetLastTouchedID(res.id)
	return renderHeartbeatSuccess(res.id, res.title)
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped cause (%v) to identify the storage-level failure.
  2. Verify storage connectivity and DB health (bd doctor).
  3. Retry the heartbeat; if persistent, check for corrupt records for that ID.
Defensive patterns

Strategy: retry

Validate before calling

// check DB health first
bd doctor --json | jq -e '.storage.ok == true'

Try / catch

if err != nil && !errors.Is(err, storage.ErrNotFound) {
	// transient storage failure: retry with backoff
}

Prevention

When it happens

Trigger: GetIssueOrWisp returns an error that is not storage.ErrNotFound (e.g. storage failure, ambiguous ID resolution error, driver fault) inside the heartbeat RunTxEphemeral transaction.

Common situations: Database lock or I/O error, driver misconfiguration in proxied mode, corrupted issue record failing unmarshalling, or transient failure during ID-prefix resolution.

Related errors


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