gastownhall/beads · warning
db: RawSQL Exec: rows affected: %w
Error message
db: RawSQL Exec: rows affected: %w
What it means
Wraps a failure from sql.Result.RowsAffected after a successful Exec in RawSQLRepository.Exec. Some drivers cannot report affected-row counts for certain statements, and the driver can also fail here if the connection state is gone. The statement executed but the library cannot tell you how many rows it touched.
Source
Thrown at internal/storage/domain/db/raw_sql.go:62
values[i] = string(b)
}
}
result.Rows = append(result.Rows, values)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("db: RawSQL Query: rows: %w", err)
}
return result, nil
}
func (r *rawSQLRepositoryImpl) Exec(ctx context.Context, query string, args ...any) (int64, error) {
res, err := r.runner.ExecContext(ctx, query, args...)
if err != nil {
return 0, fmt.Errorf("db: RawSQL Exec: %w", err)
}
affected, err := res.RowsAffected()
if err != nil {
return 0, fmt.Errorf("db: RawSQL Exec: rows affected: %w", err)
}
return affected, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Treat the count as optional — if you don't need it, prefer a driver/connection that supports RowsAffected or ignore 0
- Avoid Exec for DDL when you rely on affected counts
- Check driver support; upgrade if RowsAffected is unimplemented
- Verify connection stability — a drop right after exec yields an unusable result handle
Example fix
// before: relying on the count for a DDL statement n, err := repo.Exec(ctx, "ALTER TABLE issues ADD INDEX idx_p (priority)") // after: don't depend on the affected count for DDL _, err = repo.Exec(ctx, "ALTER TABLE issues ADD INDEX idx_p (priority)")
Defensive patterns
Strategy: fallback
Validate before calling
// don't rely on affected counts for DDL; classify the statement first isDDL := strings.HasPrefix(strings.ToUpper(strings.TrimSpace(stmt)), "ALTER") || strings.HasPrefix(strings.ToUpper(strings.TrimSpace(stmt)), "CREATE")
Type guard
func isRowsAffectedError(err error) bool {
return err != nil && strings.Contains(err.Error(), "RawSQL Exec: rows affected")
} Try / catch
n, err := repo.Exec(ctx, stmt)
if isRowsAffectedError(err) {
// statement ran; proceed treating the count as unknown
return lastErr /* or continue without the count */
} Prevention
- Ignore affected counts for DDL statements
- Confirm the driver implements RowsAffected for your statements
- Avoid multi-statement Exec calls when counts matter
- Keep connections alive through exec + result read
When it happens
Trigger: Calling Exec with a statement whose driver (or underlying engine) does not produce a rows-affected count, or where the result handle is invalid because the connection dropped after execution.
Common situations: Statements like DDL (CREATE/ALTER) or some multi-statement/SET commands where affected counts are meaningless; drivers lacking LastInsertId/RowsAffected support; connection reset immediately after exec.
Related errors
- db: LabelSQLRepository.Insert %s/%s: rows affected: %w
- failed to get rows affected: %w
- failed to check rows affected for issue counter prefix %q: %
- failed to check rows affected after seeding for prefix %q: %
- failed to check rows affected for issue counter prefix %q: %
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1e4da82b176c1e9f.
Report an issue: GitHub.