{"record":{"id":"4b72de98c7f75f6f","repo":"gastownhall/beads","slug":"hydrate-ready-row-s-comment-counts-w","errorCode":null,"errorMessage":"hydrate ready row %s: comment counts: %w","messagePattern":"hydrate ready row (.+?): comment counts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/claim_next.go","lineNumber":100,"sourceCode":"// claimed issue with no dependencies rather than saying the read failed; here\n// the whole claim rolls back instead, because a result nobody can hydrate is\n// not a result.\nfunc HydrateReadyRowInTx(ctx context.Context, tx *sql.Tx, issue *types.Issue) (*types.IssueWithCounts, error) {\n\tif issue == nil {\n\t\treturn nil, nil\n\t}\n\tids := []string{issue.ID}\n\tdepCounts, err := GetDependencyCountsInTx(ctx, tx, ids)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"hydrate ready row %s: dependency counts: %w\", issue.ID, err)\n\t}\n\trecords, err := GetDependencyRecordsForIssuesInTx(ctx, tx, ids)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"hydrate ready row %s: dependency records: %w\", issue.ID, err)\n\t}\n\tcommentCounts, err := GetCommentCountsInTx(ctx, tx, ids)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"hydrate ready row %s: comment counts: %w\", issue.ID, err)\n\t}\n\n\tissue.Dependencies = records[issue.ID]\n\tcounts := depCounts[issue.ID]\n\tif counts == nil {\n\t\tcounts = &types.DependencyCounts{}\n\t}\n\tvar parent *string\n\tfor _, dep := range records[issue.ID] {\n\t\tif dep.Type == types.DepParentChild {\n\t\t\tparent = &dep.DependsOnID\n\t\t\tbreak\n\t\t}\n\t}\n\treturn &types.IssueWithCounts{\n\t\tIssue:           issue,\n\t\tDependencyCount: counts.DependencyCount,\n\t\tDependentCount:  counts.DependentCount,","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/claim_next.go#L82-L118","documentation":"HydrateReadyRowInTx failed to read comment counts for the claimed issue via GetCommentCountsInTx. The deliberate design (documented at the function) refuses to swallow the failure: the old CLI behavior silently reported zero comments on a broken database, so now the whole claim rolls back.","triggerScenarios":"ExecuteClaimNext -> HydrateReadyRowInTx where GetCommentCountsInTx errors — missing/broken comments table, connection loss, or query failure inside the claim transaction.","commonSituations":"Schema missing a comments table after partial migration; database unavailable mid-claim; older database files opened by a newer binary expecting new tables.","solutions":["Inspect the wrapped cause for the underlying SQL error","Retry the claim after the database is reachable — no partial state was committed","Run schema checks/migrations to ensure the comments table exists and matches the binary's expectations"],"exampleFix":"if err != nil && strings.Contains(err.Error(), \"comment counts\") {\n\t// hydration failed atomically; retry once DB is verified\n\tif err := store.Ping(ctx); err == nil {\n\t\tresult, err = store.ClaimNext(ctx, req)\n\t}\n}","handlingStrategy":"retry","validationCode":"if err := store.Ping(ctx); err != nil {\n\treturn fmt.Errorf(\"database unavailable before claim: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"result, err := store.ClaimNext(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"comment counts\") {\n\t// claim rolled back; safe to retry after recovery\n\tresult, err = store.ClaimNext(ctx, req)\n}","preventionTips":["Run schema checks at startup so comment-count tables exist before claims","Avoid opening databases written by newer schema versions with older binaries","Do not treat zero counts as success — always check the error first"],"tags":["database","hydration","comments"],"backgroundTag":"comment-count-read-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}