gastownhall/beads · error
get dependent records: rows: %w
Error message
get dependent records: rows: %w
What it means
This error wraps rows.Err() after iterating dependent dependency rows — a deferred/iterative error that occurred while fetching result rows (e.g. the connection died mid-iteration). It is distinct from the initial query error and from per-row scan errors.
Source
Thrown at internal/storage/issueops/dependency_queries.go:213
return fmt.Errorf("get dependent records from %s: %w", depTable, err)
}
for rows.Next() {
dep, scanErr := scanDependentRow(rows)
if scanErr != nil {
_ = rows.Close()
return fmt.Errorf("get dependent records: scan: %w", scanErr)
}
// De-dup by row id (depid): the wisp copy of a promoted edge carries
// the same id as the durable copy scanned first, so skip the repeat.
if seen[dep.ID] {
continue
}
seen[dep.ID] = true
result[dep.DependsOnID] = append(result[dep.DependsOnID], dep)
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return fmt.Errorf("get dependent records: rows: %w", err)
}
}
return nil
}
// Target-keyed dependents-read bounds. A raw read has no consumer to apply a
// page size, so it clamps its own (default when limit <= 0, hard cap otherwise).
const (
defaultDependentRecordsLimit = 100
maxDependentRecordsLimit = 500
)
// GetDependentRecordsInTx returns raw dependency rows whose TARGET is targetID
// — the edges pointing AT targetID — from both the permanent and wisp
// dependency tables. Unlike GetDependents/GetDependentsWithMetadata it does
// NOT join or hydrate the source issues, so edges from dangling, cross-project,
// or wisp sources are returned as raw rows rather than dropped. RAW READ: it
// spans BOTH the `dependencies` and `wisp_dependencies` tables and applies noView on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped driver error — it is almost always connection- or context-related and often transient.
- Retry the read; these errors rarely indicate data problems.
- Reduce batch work per transaction or raise connection idle/read timeouts.
- Enable keepalives or connection health checks on the driver DSN.
- Ensure the context passed in has adequate deadline for large result sets.
Example fix
// before: single-shot read with a short deadline
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
deps, err := GetDependentRecordsForIssuesInTx(ctx, tx, ids)
// after: deadline sized to the workload, retry on transient rows errors
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
deps, err := GetDependentRecordsForIssuesInTx(ctx, tx, ids)
if err != nil && isTransientNetError(err) { deps, err = GetDependentRecordsForIssuesInTx(ctx, tx, ids) } Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: confirm the connection is alive before long batch reads
if err := tx.QueryRowContext(ctx, "SELECT 1").Scan(&one); err != nil {
return fmt.Errorf("connection unhealthy before dependent-records read: %w", err)
} Type guard
func isTransientRowError(err error) bool {
if err == nil { return false }
msg := err.Error()
return strings.Contains(msg, "connection") || strings.Contains(msg, "bad connection") || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
} Try / catch
err := getDependentRecordsIntoFromTable(ctx, tx, table, ids, seen, result)
if err != nil && strings.Contains(err.Error(), "rows: ") && isTransientRowError(err) {
err = retryWithBackoff(3, func() error { return getDependentRecordsIntoFromTable(ctx, tx, table, ids, seen, result) })
} Prevention
- Raise connection idle/read timeouts for batch workloads
- Size the context deadline to the number of batches
- Enable TCP keepalives on the database DSN
- Avoid holding transactions open across slow application logic
When it happens
Trigger: Calling GetDependentRecordsForIssuesInTx when the database connection drops or the context is canceled while streaming rows between rows.Next() calls, or a driver-level protocol error occurs during row retrieval.
Common situations: Long-running batched reads over many target IDs hitting a connection idle timeout; network flakiness to a remote Dolt/MySQL server; server-side kill of a long query.
Related errors
- iter issues: rows: %w
- iterate dependency sources: %w
- iterate dependency targets: %w
- count edges in %s: rows: %w
- search %s (hydrate): rows: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0c25c7433b053795.
Report an issue: GitHub.