gastownhall/beads · error

hydrate dependencies: %w

Error message

hydrate dependencies: %w

What it means

Raised inside hydrateIssues when getDependencyRecordsFromTable fails fetching dependency records for the hydrated issue IDs, wrapped as "hydrate dependencies: <err>". This only runs when the caller sets filter.IncludeDependencies, so it appears on dependency-inclusive searches.

Source

Thrown at internal/storage/domain/db/issue_search.go:349

		ids[i] = issue.ID
	}

	if !skipLabels {
		labelMap, err := r.getLabelsFromTable(ctx, tables.Labels, ids)
		if err != nil {
			return fmt.Errorf("hydrate labels: %w", err)
		}
		for _, issue := range issues {
			if labels, ok := labelMap[issue.ID]; ok {
				issue.Labels = labels
			}
		}
	}

	if includeDeps {
		depMap, err := r.getDependencyRecordsFromTable(ctx, tables.Dependencies, ids)
		if err != nil {
			return fmt.Errorf("hydrate dependencies: %w", err)
		}
		for _, issue := range issues {
			if deps, ok := depMap[issue.ID]; ok {
				issue.Dependencies = deps
			}
		}
	}

	return nil
}

//nolint:gosec // G201: labelTable is "labels" or "wisp_labels" (hardcoded by callers).
func (r *issueSQLRepositoryImpl) getLabelsFromTable(ctx context.Context, labelTable string, ids []string) (map[string][]string, error) {
	result := make(map[string][]string)
	for start := 0; start < len(ids); start += queryBatchSize {
		end := start + queryBatchSize
		if end > len(ids) {
			end = len(ids)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the error to identify the failing statement and cause.
  2. Run migrations / `bd doctor` to ensure the dependencies table exists and matches the schema.
  3. Repair rows with NULL or dangling issue_id/depends_on values.
  4. If dependencies are optional for your use case, set filter.IncludeDependencies=false to bypass hydration.

Example fix

// before
filter := types.IssueFilter{IncludeDependencies: true} // dependencies table missing
// after
bd doctor && bd migrate // create/repair tables
filter := types.IssueFilter{IncludeDependencies: true}
Defensive patterns

Strategy: fallback

Validate before calling

if err := bd.CheckTables(dbPath, "dependencies"); err != nil {
	// proceed without dependencies rather than failing
	filter.IncludeDependencies = false
}

Type guard

func isDepHydrateError(err error) bool {
	return err != nil && strings.HasPrefix(err.Error(), "hydrate dependencies: ")
}

Try / catch

page, err := store.Search(ctx, q, types.IssueFilter{IncludeDependencies: true})
if err != nil && isDepHydrateError(err) {
	// fall back to dependency-free search
	page, err = store.Search(ctx, q, types.IssueFilter{})
}

Prevention

When it happens

Trigger: With IncludeDependencies=true, the query against the dependencies (or wisp dependencies) table fails: table missing, locked DB, connection loss, or unscannable dependency rows (NULL issue_id/depends_on).

Common situations: Database predating the dependencies table; manually edited dependency rows; Dolt replication conflict leaving NULL foreign keys; lock contention with a concurrent bd mutator.

Related errors


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