gastownhall/beads · error

hydrate ready row %s: comment counts: %w

Error message

hydrate ready row %s: comment counts: %w

What it means

hydrateReadyRow fetches comment counts for the claimed issue via CommentUseCase().GetCommentCounts and wraps any failure. This is the third hydration step (after dependency counts and records); failing here aborts the claim so a partially hydrated result is never returned to the caller.

Source

Thrown at internal/storage/uow/ready_claimer.go:112

// hydrateReadyRow fills in the relationship cardinalities a ready row carries,
// reading them in the caller's unit of work so the counts describe the state
// that transaction is about to commit. A failed count read is an error rather
// than a zero, matching the store-backed sibling: a result nobody can hydrate
// is not a result.
func hydrateReadyRow(ctx context.Context, uw UnitOfWork, issue *types.Issue) (*types.IssueWithCounts, error) {
	ids := []string{issue.ID}
	depCounts, err := uw.DependencyUseCase().CountsByIssueIDs(ctx, ids)
	if err != nil {
		return nil, fmt.Errorf("hydrate ready row %s: dependency counts: %w", issue.ID, err)
	}
	records, err := uw.DependencyUseCase().GetForIssueIDs(ctx, ids)
	if err != nil {
		return nil, fmt.Errorf("hydrate ready row %s: dependency records: %w", issue.ID, err)
	}
	commentCounts, err := uw.CommentUseCase().GetCommentCounts(ctx, ids)
	if err != nil {
		return nil, fmt.Errorf("hydrate ready row %s: comment counts: %w", issue.ID, err)
	}

	issue.Dependencies = records[issue.ID]
	counts := depCounts[issue.ID]
	if counts == nil {
		counts = &types.DependencyCounts{}
	}
	var parent *string
	for _, dep := range records[issue.ID] {
		if dep.Type == types.DepParentChild {
			parent = &dep.DependsOnID
			break
		}
	}
	return &types.IssueWithCounts{
		Issue:           issue,
		DependencyCount: counts.DependencyCount,
		DependentCount:  counts.DependentCount,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the claim/ready command
  2. Inspect the wrapped underlying error (%w) via server logs or verbose output
  3. Check grants on the comments table
  4. Increase timeouts if comment count queries are slow

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// Go: pre-verify comment counts are computable
_, err := uw.CommentUseCase().GetCommentCounts(ctx, []string{issueID})
if err != nil { /* resolve access/perf issues before claiming */ }

Type guard

func isCommentCountHydrationError(err error) bool {
  return err != nil && strings.Contains(err.Error(), "comment counts: ")
}

Try / catch

issue, err := ClaimNextInUOW(ctx)
if isCommentCountHydrationError(err) {
  // transient: back off and retry once before surfacing
  time.Sleep(time.Second); issue, err = ClaimNextInUOW(ctx)
}
return issue, err

Prevention

When it happens

Trigger: ClaimNextInUOW → hydrateReadyRow where GetCommentCounts(ctx, [issueID]) errors — SQL failure, connection loss, or comment use-case error while counting comments for the claimed issue.

Common situations: Dolt server error during 'bd ready'; permission problems on comment tables; large comment tables making the count query time out; transient network interruption.

Related errors


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