gastownhall/beads · error
iterate dependency targets: %w
Error message
iterate dependency targets: %w
What it means
This error wraps rows.Err() after iterating the dependency-target result set in replaceDependencyTargetInTx. It reports streaming errors that occur mid-iteration (connection loss, killed query, replication error), as opposed to the initial query or per-row scan failures.
Source
Thrown at internal/storage/issueops/dependencies.go:745
}
switch column {
case "depends_on_issue_id":
row.issueTarget = sql.NullString{String: newID, Valid: true}
row.wispTarget = sql.NullString{}
row.external = sql.NullString{}
case "depends_on_wisp_id":
row.issueTarget = sql.NullString{}
row.wispTarget = sql.NullString{String: newID, Valid: true}
row.external = sql.NullString{}
default:
_ = queryRows.Close()
return fmt.Errorf("replace dependency target: unsupported typed column %q", column)
}
rows = append(rows, row)
}
_ = queryRows.Close()
if err := queryRows.Err(); err != nil {
return fmt.Errorf("iterate dependency targets: %w", err)
}
//nolint:gosec // table and column are hardcoded by callers.
if _, err := tx.ExecContext(ctx, fmt.Sprintf(`DELETE FROM %s WHERE %s = ? OR (%s = ? AND depends_on_external IS NULL)`, table, column, DepTargetExpr), oldID, oldID); err != nil {
return fmt.Errorf("delete old dependency target: %w", err)
}
for _, row := range rows {
// The retargeted edge's natural key is (issue_id, newID): the switch above
// set exactly one typed target column to newID. Re-derive id from it so the
// rewritten row stays merge-safe and keeps a clone-stable primary key (#4259).
//nolint:gosec // table is hardcoded by callers.
if _, err := tx.ExecContext(ctx, fmt.Sprintf(`
INSERT INTO %s (id, issue_id, depends_on_issue_id, depends_on_wisp_id, depends_on_external, type, created_at, created_by, metadata, thread_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`, table), depid.New(row.issueID, newID), row.issueID, nullStringValue(row.issueTarget), nullStringValue(row.wispTarget), nullStringValue(row.external), row.depType, nullTimeValue(row.createdAt), nullStringValue(row.createdBy), nullStringValue(row.metadata), nullStringValue(row.threadID)); err != nil {
return fmt.Errorf("insert replacement dependency target: %w", err)
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped driver error for the underlying cause
- Retry the rename; the transaction ensures no partial delete/reinsert state persists
- Raise query timeouts or batch the rename into smaller groups of issues
- Check server logs for aborted queries at the failure time
Defensive patterns
Strategy: retry
Validate before calling
// Preflight: connection health and expected row count
if err := db.PingContext(ctx); err != nil { return err }
var n int
db.Get(&n, `SELECT COUNT(*) FROM dependencies WHERE depends_on_issue_id = ? OR depends_on_wisp_id = ?`, oldID, oldID)
log.Printf("retargeting %d dependency rows", n) Try / catch
for attempt := 0; attempt < 3; attempt++ {
err := renameWithDeps(tx, oldID, newID)
if err == nil { break }
if !isTransient(err) { return err }
time.Sleep(backoff(attempt)) // whole tx rolled back; retry is safe
} Prevention
- Increase driver readTimeout for renames touching many edges
- Retry complete operations only — the delete/reinsert pair is atomic per transaction
- Avoid renames during replica failover windows
- Split very large renames into batches of issues
When it happens
Trigger: UpdateIssueIDInTx / UpdateWispIDInTx rename, while streaming rows matching the old target ID from dependencies or wisp_dependencies: the result stream errors after partial reads.
Common situations: Large edge fan-in/out to a single renamed issue causing a slow scan that hits a timeout; network interruption to the Dolt/MySQL server; server shutdown mid-query.
Related errors
- iterate dependency sources: %w
- count edges in %s: rows: %w
- search %s (hydrate): rows: %w
- db: ChildCounterSQLRepository.NextChildID: rows: %w
- db: CommentSQLRepository.CountsByIssueIDs: rows: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c1fbb462f8586fe6.
Report an issue: GitHub.