gastownhall/beads · error

ready work union with counts: hydrate wisps: %w

Error message

ready work union with counts: hydrate wisps: %w

What it means

This error wraps a failure that occurred while hydrating wisp rows (lightweight issues) with their issue counts during the 'ready work with counts' union query. The union query already fetched the paged IDs; hydration via fetchCountsByIDs then queries per-table count data. Any SQL error other than a benign 'table does not exist' is wrapped here, so the message indicates the underlying Dolt/SQL error after 'hydrate wisps:'.

Source

Thrown at internal/storage/domain/db/ready_work_union.go:129

	}

	page, hasMore, err := r.getReadyWorkIDPage(ctx, filter)
	if err != nil {
		return domain.SearchCountsPage{}, err
	}
	if len(page.ordered) == 0 {
		return domain.SearchCountsPage{Items: nil, HasMore: hasMore}, nil
	}

	issuesByID, err := r.fetchCountsByIDs(ctx, page.issueIDs, issuesFilterTables, wispDepsExist, readyHydrationFor(filter))
	if err != nil {
		return domain.SearchCountsPage{}, fmt.Errorf("ready work union with counts: hydrate issues: %w", err)
	}
	var wispsByID map[string]*types.IssueWithCounts
	if len(page.wispIDs) > 0 {
		wispsByID, err = r.fetchCountsByIDs(ctx, page.wispIDs, wispsFilterTables, true, readyHydrationFor(filter))
		if err != nil && !dberrors.IsTableNotExist(err) {
			return domain.SearchCountsPage{}, fmt.Errorf("ready work union with counts: hydrate wisps: %w", err)
		}
	}

	return domain.SearchCountsPage{
		Items:   reassembleBySrc(page.ordered, issuesByID, wispsByID),
		HasMore: hasMore,
	}, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped cause after 'hydrate wisps:' to identify the real SQL error
  2. Check database schema integrity (run bd doctor / migrations) to ensure wisp count tables exist and are valid
  3. Retry the operation if the cause is a transient connection/timeout error
  4. If a required table is genuinely missing, run the schema migration instead of expecting hydration to skip it (only missing tables are tolerated)

Example fix

// before
page, err := store.GetReadyWorkWithCounts(ctx, filter)
if err != nil { return err }
// after
page, err := store.GetReadyWorkWithCounts(ctx, filter)
if err != nil {
    if dberrors.IsTableNotExist(errors.Unwrap(errors.Unwrap(err))) { /* treat as empty counts */ }
    log.Errorf("ready work counts failed: %v", err)
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify DB connectivity and schema before calling
if err := pingDB(ctx); err != nil { return err }
// note: missing wisp count tables are tolerated internally (IsTableNotExist)

Type guard

func isHydrationErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "hydrate wisps:")
}

Try / catch

page, err := store.GetReadyWorkWithCounts(ctx, filter)
if err != nil {
    var cause error
    for errors.Unwrap(err) != nil { cause = errors.Unwrap(err) }
    if dberrors.IsTableNotExist(cause) { /* fall back to no-counts query */ }
    return fmt.Errorf("ready work unavailable: %w", err)
}

Prevention

When it happens

Trigger: Calling GetReadyWorkWithCounts when the result page contains wisp IDs and fetchCountsByIDs fails with a SQL error that is not dberrors.IsTableNotExist — e.g. malformed wispsFilterTables, connection drop mid-query, SQL syntax/permission error, or context cancellation during the count hydration query.

Common situations: Upgraded or partially migrated database where wisp count tables are corrupt or inaccessible; transient Dolt server connection loss; query timeout/cancelled context while loading the ready-work board with counts; schema drift between beads version and database.

Related errors


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