gastownhall/beads · error
db: Update %s: rows affected: %w
Error message
db: Update %s: rows affected: %w
What it means
Wrapped failure from res.RowsAffected() after the UPDATE executed: the driver could not report how many rows the statement changed. This is a driver/protocol-level problem, distinct from a zero-row result (which yields sql.ErrNoRows instead). The unit of work aborts even though the UPDATE may have been applied.
Source
Thrown at internal/storage/domain/db/issue.go:280
// status/ownership mutation collides on this shared cell instead of
// silently cell-merging, and the row's RowVersion CAS token advances so
// the "generic update path changes RowVersion" contract
// (types.Issue.RowVersion) holds on the proxied backend too.
rowLockClause, rowLockArgs := issueops.RowLockClause()
setClauses = append(setClauses, rowLockClause)
args = append(args, rowLockArgs...)
args = append(args, id)
//nolint:gosec // G201: table is one of two hardcoded constants
q := fmt.Sprintf("UPDATE %s SET %s WHERE id = ?", table, strings.Join(setClauses, ", "))
res, err := r.runner.ExecContext(ctx, q, args...)
if err != nil {
return fmt.Errorf("db: Update %s: %w", id, err)
}
rows, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("db: Update %s: rows affected: %w", id, err)
}
if rows == 0 {
return fmt.Errorf("db: Update %s: %w", id, sql.ErrNoRows)
}
if clearLease && !opts.UseWispsTable {
if err := issueops.DeleteLeaseInTx(ctx, r.runner, id); err != nil {
return fmt.Errorf("db: Update %s: clear lease: %w", id, err)
}
}
// Event-type parity: embedded records EventClosed / EventReopened /
// EventStatusChanged for status transitions (issueops.DetermineEventType),
// EventUpdated otherwise.
eventType := types.EventUpdated
if statusChanging {
eventType = issueops.DetermineEventType(oldIssue, updates)
}
if err := r.events.Record(ctx, domain.Event{View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped driver error and driver/server versions; upgrade the Dolt driver/server to a compatible pair.
- Retry the unit of work on a fresh connection; verify whether the update landed (read the row) before re-writing.
- Avoid proxy/middleware that interferes with result metadata.
- If reproducible, report the driver issue — this path should never error on a healthy server.
Example fix
// before
if err := repo.Update(ctx, id, updates, actor, opts); err != nil { return err }
// after: verify state before retrying
if err := repo.Update(ctx, id, updates, actor, opts); err != nil && isRowsAffectedErr(err) {
if iss, _ := repo.Get(ctx, id, opts); iss == nil || !applied(iss, updates) { retry() }
} Defensive patterns
Strategy: fallback
Validate before calling
// detect a driver that cannot report rows affected (best-effort probe)
_, err := conn.ExecContext(ctx, "SELECT 1")
if err != nil { /* degraded driver — avoid write paths or verify by read-back */ } Try / catch
if err := repo.Update(ctx, id, updates, actor, opts); err != nil && strings.Contains(err.Error(), "rows affected") {
// verify outcome by reading the row before retrying
iss, gerr := repo.Get(ctx, id, opts)
if gerr == nil && updateApplied(iss, updates) { return nil }
return retry(freshCtx)
} Prevention
- Keep the Dolt driver and server versions compatible
- Verify the update landed via Get before blind retries
- Remove proxies that strip result metadata
- Report persistent RowsAffected failures as driver bugs
When it happens
Trigger: Calling Update when the underlying driver (dolthub/driver via database/sql) fails to return rows-affected metadata — protocol mismatch, connection in a bad state after ExecContext, or a driver that does not support RowsAffected for this statement.
Common situations: Bugs or version skew in the Dolt driver; a connection dropped between ExecContext and RowsAffected; proxying layers that strip result metadata.
Related errors
- failed to check rows affected for issue counter prefix %q: %
- failed to check rows affected after seeding for prefix %q: %
- db: DependencySQLRepository.DeleteAllForIDs rows affected: %
- db: EventsSQLRepository.DeleteAllForIDs rows affected: %w
- db: Claim %s: rows affected: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c388c97182494b4f.
Report an issue: GitHub.