{"record":{"id":"0b893e9d3cce220f","repo":"gastownhall/beads","slug":"ready-claim-of-s-reported-success-but-could-not-b","errorCode":null,"errorMessage":"ready claim of %s reported success but could not be verified (server degraded?): %w — re-read the issue before trusting the claim","messagePattern":"ready claim of (.+?) reported success but could not be verified \\(server degraded\\?\\): %w — re-read the issue before trusting the claim","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/issues.go","lineNumber":433,"sourceCode":"// (bd-zccb9): the claimed ID is only known once the write body has run, so\n// this cannot ride verifiedClaimWrite's id parameter — but the resolution\n// protocol is the same. Split from ClaimReadyIssue so injection tests can\n// drive the write seam directly, the same way the verifiedClaimWrite tests do.\n//\n// Successful ready claims verify the winning plane because IncludeEphemeral\n// may select a wisp. An indeterminate commit response remains indeterminate:\n// assignee and status cannot prove the lease and actor-attributed event landed.\nfunc (s *DoltStore) verifiedReadyClaim(ctx context.Context, actor string, write func() (*types.Issue, error)) (*types.Issue, error) {\n\tclaimed, err := write()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif claimed == nil || !s.serverMode {\n\t\treturn claimed, err\n\t}\n\tassignee, status, verr := s.readReadyClaimState(ctx, claimed.ID)\n\tif verr != nil {\n\t\treturn nil, fmt.Errorf(\"ready claim of %s reported success but could not be verified (server degraded?): %w — re-read the issue before trusting the claim\",\n\t\t\tclaimed.ID, verr)\n\t}\n\tpost := claimedBy(actor)\n\tif post.want(assignee, status) {\n\t\treturn claimed, nil\n\t}\n\tdoltMetrics.claimVerifyLost.Add(ctx, 1, metric.WithAttributes(\n\t\tattribute.String(\"op\", \"ready-claim\")))\n\treturn nil, fmt.Errorf(\"ready claim of %s reported success but did not land (found assignee=%q status=%q, want %s) — server likely degraded; treat the claim as NOT applied\",\n\t\tclaimed.ID, assignee, status, post.desc)\n}\n\n// HeartbeatIssue refreshes the lease on an issue actor holds in_progress,\n// pushing lease_expires_at forward on its row in the ephemeral leases table\n// (see issueops.lease). Deliberately NO DOLT_ADD/DOLT_COMMIT: the leases\n// table is dolt_ignored, so a heartbeat mints no commit and no history — this\n// is the whole point of bd-lrgn1 (fleet heartbeats were the dominant source\n// of unbounded reachable history). Wrapped in withRetryTx so a heartbeat that","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/issues.go#L415-L451","documentation":"verifiedReadyClaim re-reads an issue from the server after a successful ready-claim write; if the verification read itself fails while in server mode, the success cannot be trusted. The library returns the underlying read error wrapped in this message, instructing the caller to re-read before trusting the claim.","triggerScenarios":"A bd ready --claim (or equivalent storage call) succeeds on the write path, but the subsequent readReadyClaimState query fails due to a transient server/connection error, while s.serverMode is true.","commonSituations":"Dolt server restart or network blip between the claim write and verification read; server-side connection pool exhaustion; timeouts under load.","solutions":["Re-read the issue (or retry the ready claim) to learn its actual assignee/status","Retry the whole claim operation; the store uses retry transactions, so a transient read failure often clears on retry","Check that the Dolt SQL server is reachable and healthy (bd doctor, connection settings)","If verification keeps failing, treat the claim as unverified and avoid making decisions based on it"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before trusting any claim, verify server reachability\nconst healthy = await checkServerHealth(); // e.g. run a trivial query\nif (!healthy) throw new Error(\"server unavailable; do not claim\");","typeGuard":"function isVerifiedClaim(result) {\n  return result !== null && typeof result === \"object\" && result.id && !String(result.message ?? \"\").includes(\"could not be verified\");\n}","tryCatchPattern":"try {\n  const claimed = await bd.readyClaim(actor);\n} catch (e) {\n  if (String(e.message).includes(\"could not be verified\")) {\n    const issue = await bd.show(id); // re-read before trusting\n    // decide whether to retry the claim\n  } else throw e;\n}","preventionTips":["Ensure the Dolt server is healthy and reachable before claim loops","Retry claims on transient verification failures with backoff","Never act on a claim until its state has been re-read","Monitor server logs for errors between write and read"],"tags":["verification","server-degraded","claim","transient"],"backgroundTag":"claim-verification-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}