gastownhall/beads · error

get dependents: fetch issues: %w

Error message

get dependents: fetch issues: %w

What it means

GetDependentsWithMetadataInTx wraps any error from GetIssuesByIDsInTx when loading the issue records for the dependent IDs it just collected. The dependency edges read fine; hydrating the dependent issues themselves failed, with the underlying cause preserved via %w.

Source

Thrown at internal/storage/issueops/dependencies.go:1200

		}
		_ = rows.Close()
		if err := rows.Err(); err != nil {
			return nil, fmt.Errorf("get dependents: rows from %s: %w", depTable, err)
		}
	}

	if len(deps) == 0 {
		return nil, nil
	}

	// Fetch all dependent issues.
	ids := make([]string, len(deps))
	for i, d := range deps {
		ids[i] = d.depID
	}
	issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)
	if err != nil {
		return nil, fmt.Errorf("get dependents: fetch issues: %w", err)
	}
	issueMap := make(map[string]*types.Issue, len(issues))
	for _, iss := range issues {
		issueMap[iss.ID] = iss
	}

	var results []*types.IssueWithDependencyMetadata
	for _, d := range deps {
		issue, ok := issueMap[d.depID]
		if !ok {
			continue
		}
		results = append(results, &types.IssueWithDependencyMetadata{
			Issue:          *issue,
			DependencyType: types.DependencyType(d.depType),
		})
	}
	return results, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the %w chain to the GetIssuesByIDsInTx sub-error and address that specific failure.
  2. Check for orphan rows: dependent IDs that don't exist in either issue table (the code skips missing ones, but fetch errors still propagate).
  3. Verify the issues/wisp_issues schema matches what ScanIssueFrom expects.
  4. Retry on a fresh transaction if the cause is transient.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify dependent IDs resolve to real issues before hydration
ids, err := collectDependentIDs(ctx, tx, issueID)
if err != nil { return err }
for _, id := range ids {
    if !issueExists(ctx, tx, id) { log.Printf("orphan dependent row: %s", id) }
}

Type guard

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

Try / catch

deps, err := GetDependentsWithMetadataInTx(ctx, tx, issueID)
if err != nil {
    if isHydrationErr(err) {
        log.Printf("dependent issue hydration failed: %v", errors.Unwrap(err))
    }
    return err
}

Prevention

When it happens

Trigger: GetDependentsWithMetadataInTx found dependent rows, then the batched SELECT via GetIssuesByIDsInTx over those issue IDs failed — query error, scan mismatch, rows error, or label-hydration error inside that helper.

Common situations: Orphaned dependency rows referencing IDs missing from issues/wisp_issues combined with strict schema checks; very large fan-out exceeding parameter limits; transient DB failure; schema drift in the issues tables.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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