gastownhall/beads · error
get issues by IDs: label rows: %w
Error message
get issues by IDs: label rows: %w
What it means
Wraps the labelRows.Err() check after iterating hydrated label rows in GetIssuesByIDsInTx. The scan loop completed but the result set hit a driver/connection error at the end of iteration.
Source
Thrown at internal/storage/issueops/dependencies.go:1085
labelRows, err := tx.QueryContext(ctx, fmt.Sprintf(
`SELECT issue_id, label FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, label`,
pair.labelTbl, inClause), args...)
if err != nil {
return nil, fmt.Errorf("get issues by IDs: labels from %s: %w", pair.labelTbl, err)
}
for labelRows.Next() {
var issueID, label string
if scanErr := labelRows.Scan(&issueID, &label); scanErr != nil {
_ = labelRows.Close()
return nil, fmt.Errorf("get issues by IDs: scan label: %w", scanErr)
}
if issue, ok := issueMap[issueID]; ok {
issue.Labels = append(issue.Labels, label)
}
}
_ = labelRows.Close()
if err := labelRows.Err(); err != nil {
return nil, fmt.Errorf("get issues by IDs: label rows: %w", err)
}
}
}
}
return allIssues, nil
}
// GetDependenciesWithMetadataInTx returns issues that the given issueID depends on,
// along with the dependency type. Works within an existing transaction.
// Queries both dependency tables to handle cross-table dependencies.
//
//nolint:gosec // G201: table names come from hardcoded constants
func GetDependenciesWithMetadataInTx(ctx context.Context, tx DBTX, issueID string) ([]*types.IssueWithDependencyMetadata, error) {
type depMeta struct {
depID, depType string
}
View on GitHub (pinned to 71377f2769)
Solutions
- Retry — the fetch is read-only and idempotent
- Check upstream context cancellation/timeout settings
- Investigate network/proxy idle timeouts if this recurs on large sets
Defensive patterns
Strategy: retry
Validate before calling
// Ensure adequate deadline and healthy pool before batch fetches:
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil { return err } Try / catch
issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)
if err != nil && strings.Contains(err.Error(), "label rows") {
if errors.Is(err, context.Canceled) { return err } // don't retry cancels
if isTransientDBError(err) {
issues, err = GetIssuesByIDsInTx(ctx, tx, ids, nil) // one retry
}
} Prevention
- Size label fetches reasonably (large ID lists iterate longer)
- Set proxy/idle timeouts above worst-case query duration
- Retry read-only fetches freely — they are idempotent
- Check for upstream context cancellation first when diagnosing
When it happens
Trigger: After consuming all label rows, labelRows.Err() returns non-nil — connection dropped, context canceled, or driver streaming error during iteration.
Common situations: Client timeout canceling the context mid-iteration; unstable connection to the DB; large label result sets iterating longer than the connection allows.
Related errors
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to query orphaned dependencies: %w
- row iteration error: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/543dc739858050fe.
Report an issue: GitHub.