gastownhall/beads · error
resolving %s: %w
Error message
resolving %s: %w
What it means
When `workapi.GetIssueOrWisp` fails with an error other than `storage.ErrNotFound`, `uowMolReader.GetIssue` wraps it as `resolving %s: %w`, preserving the underlying cause. This distinguishes 'ID simply absent' (1086) from 'lookup failed' — storage errors, malformed ID resolution, or transaction failures inside the unit of work.
Source
Thrown at cmd/bd/mol_port.go:130
return tx.UpdateIssue(ctx, id, map[string]interface{}{"status": types.StatusInProgress}, actor)
})
}
func newStandaloneStoreMolWriter(store storage.DoltStorage) storeMolWriter {
return storeMolWriter{DoltStorage: store}
}
type uowMolReader struct {
uw uow.UnitOfWork
}
func (r uowMolReader) GetIssue(ctx context.Context, id string) (*types.Issue, error) {
issue, isWisp, rerr := workapi.GetIssueOrWisp(ctx, workapi.NewUOWDetailSource(r.uw), id)
if errors.Is(rerr, storage.ErrNotFound) {
return nil, fmt.Errorf("issue %s not found", id)
}
if rerr != nil {
return nil, fmt.Errorf("resolving %s: %w", id, rerr)
}
// READS, ALL OF THEM, and they stay for the reason the writes did not.
// uowMolReader is a PORT: it adapts a caller's open unit of work to the
// molecule commands' reader interface, and every method here must answer
// from inside that transaction. issueops.Reader opens one of its own, so a
// role-routed port would show the molecule the last committed state while
// the command that owns the transaction is midway through changing it.
// A reader role bound to a caller's transaction is the follow-up
// (ga-2ltro.12). The wisp branch here is a read that follows the row
// GetIssueOrWisp already found, not a front door choosing where to write.
var labels []string
var err error
if isWisp {
labels, err = r.uw.LabelUseCase().GetWispLabels(ctx, id) //nolint:forbidigo // in-transaction port read; issueops.Reader would open its own
} else {
labels, err = r.uw.LabelUseCase().GetLabels(ctx, id) //nolint:forbidigo // in-transaction port read; issueops.Reader would open its own
}
if err == nil {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause (unwrap `%w`) — fix the underlying storage/transaction error it reports.
- Re-run `bd doctor` to check database health and connectivity.
- Ensure reads happen while the caller's unit of work is open and valid; recreate the reader if the transaction was closed.
- Retry the command if the storage error was transient (e.g. lock contention).
Example fix
// before
issue, err := reader.GetIssue(ctx, id) // opaque failure
// after
issue, err := reader.GetIssue(ctx, id)
if err != nil && strings.HasPrefix(err.Error(), "resolving ") {
log.Printf("lookup failed: %v", errors.Unwrap(err)) // see real cause
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check storage health before molecule reads
bd doctor --json | jq -e '.healthy' >/dev/null || { echo "database unhealthy"; exit 1; } Try / catch
iss, err := reader.GetIssue(ctx, id)
if err != nil {
var cause error = err
for errors.Unwrap(cause) != nil {
cause = errors.Unwrap(cause)
}
if errors.Is(cause, storage.ErrNotFound) {
return nil
}
return fmt.Errorf("transient lookup failure, retry: %w", err)
} Prevention
- Run `bd doctor` after version upgrades or crashes before batch reads.
- Keep reads inside the caller's open unit of work; don't reuse stale readers.
- Add bounded retries with backoff for storage-layer errors.
When it happens
Trigger: Any non-NotFound error from the resolver while `GetMoleculeProgress`, `GetMoleculeLastActivity`, `runMolBurnProxiedServer`, or `runWispCreateProxiedServer` reads an ID: database I/O failure, closed/invalid unit of work, corrupted storage, or driver-level errors surfaced by `GetIssueOrWisp`.
Common situations: Dolt database unavailable or locked; calling reader methods outside a valid transaction lifetime; disk/permission problems on the storage backend; transient driver failures during heavy parallel reads.
Related errors
- not found
- resolving ID %s: %w
- failed to check parent issue: %w
- canonical issue not found: %s
- failed to add supersede link: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/dca9f485c018d1c3.
Report an issue: GitHub.