{"record":{"id":"dca9f485c018d1c3","repo":"gastownhall/beads","slug":"resolving-s-w-dca9f4","errorCode":null,"errorMessage":"resolving %s: %w","messagePattern":"resolving (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/mol_port.go","lineNumber":130,"sourceCode":"\t\treturn tx.UpdateIssue(ctx, id, map[string]interface{}{\"status\": types.StatusInProgress}, actor)\n\t})\n}\n\nfunc newStandaloneStoreMolWriter(store storage.DoltStorage) storeMolWriter {\n\treturn storeMolWriter{DoltStorage: store}\n}\n\ntype uowMolReader struct {\n\tuw uow.UnitOfWork\n}\n\nfunc (r uowMolReader) GetIssue(ctx context.Context, id string) (*types.Issue, error) {\n\tissue, isWisp, rerr := workapi.GetIssueOrWisp(ctx, workapi.NewUOWDetailSource(r.uw), id)\n\tif errors.Is(rerr, storage.ErrNotFound) {\n\t\treturn nil, fmt.Errorf(\"issue %s not found\", id)\n\t}\n\tif rerr != nil {\n\t\treturn nil, fmt.Errorf(\"resolving %s: %w\", id, rerr)\n\t}\n\t// READS, ALL OF THEM, and they stay for the reason the writes did not.\n\t// uowMolReader is a PORT: it adapts a caller's open unit of work to the\n\t// molecule commands' reader interface, and every method here must answer\n\t// from inside that transaction. issueops.Reader opens one of its own, so a\n\t// role-routed port would show the molecule the last committed state while\n\t// the command that owns the transaction is midway through changing it.\n\t// A reader role bound to a caller's transaction is the follow-up\n\t// (ga-2ltro.12). The wisp branch here is a read that follows the row\n\t// GetIssueOrWisp already found, not a front door choosing where to write.\n\tvar labels []string\n\tvar err error\n\tif isWisp {\n\t\tlabels, err = r.uw.LabelUseCase().GetWispLabels(ctx, id) //nolint:forbidigo // in-transaction port read; issueops.Reader would open its own\n\t} else {\n\t\tlabels, err = r.uw.LabelUseCase().GetLabels(ctx, id) //nolint:forbidigo // in-transaction port read; issueops.Reader would open its own\n\t}\n\tif err == nil {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/mol_port.go#L112-L148","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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)."],"exampleFix":"// before\nissue, err := reader.GetIssue(ctx, id) // opaque failure\n// after\nissue, err := reader.GetIssue(ctx, id)\nif err != nil && strings.HasPrefix(err.Error(), \"resolving \") {\n    log.Printf(\"lookup failed: %v\", errors.Unwrap(err)) // see real cause\n}","handlingStrategy":"try-catch","validationCode":"// pre-check storage health before molecule reads\nbd doctor --json | jq -e '.healthy' >/dev/null || { echo \"database unhealthy\"; exit 1; }","typeGuard":null,"tryCatchPattern":"iss, err := reader.GetIssue(ctx, id)\nif err != nil {\n\tvar cause error = err\n\tfor errors.Unwrap(cause) != nil {\n\t\tcause = errors.Unwrap(cause)\n\t}\n\tif errors.Is(cause, storage.ErrNotFound) {\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"transient lookup failure, retry: %w\", err)\n}","preventionTips":["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."],"tags":["cli","storage","error-wrapping"],"backgroundTag":"storage-lookup-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}