plandex-ai/plandex · error
Error getting rows affected:
Error message
Error getting rows affected:
What it means
After the archive UPDATE succeeded, res.RowsAffected() returned an error, so the handler responds HTTP 500 with 'Error getting rows affected'. With lib/pq this happens when the result has no row-count data (e.g. the driver couldn't report rows affected for the statement).
Source
Thrown at app/server/handlers/plans_changes.go:467
if plan.ArchivedAt != nil {
log.Println("Plan already archived")
http.Error(w, "Plan already archived", http.StatusBadRequest)
return
}
res, err := db.Conn.Exec("UPDATE plans SET archived_at = NOW() WHERE id = $1", planId)
if err != nil {
log.Printf("Error archiving plan: %v\n", err)
http.Error(w, "Error archiving plan: "+err.Error(), http.StatusInternalServerError)
return
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Printf("Error getting rows affected: %v\n", err)
http.Error(w, "Error getting rows affected: "+err.Error(), http.StatusInternalServerError)
return
}
if rowsAffected == 0 {
log.Println("Plan not found")
http.Error(w, "Not found", http.StatusNotFound)
return
}
log.Println("Successfully archived plan", planId)
}
func UnarchivePlanHandler(w http.ResponseWriter, r *http.Request) {
auth := Authenticate(w, r, true)
if auth == nil {
return
}
View on GitHub (pinned to e2d772072e)
Solutions
- Check the appended err.Error() for the driver-specific reason
- Verify the expected Postgres driver (lib/pq or pgx stdlib) is in use — some drivers don't support RowsAffected for all statements
- If the driver can't report rows, use a RETURNING clause or a SELECT count instead
- Retry the request; if persistent, pin/upgrade the driver version
Example fix
// before
res, err := db.Conn.Exec("UPDATE plans SET archived_at = NOW() WHERE id = $1", planId)
rows, _ := res.RowsAffected()
// after
var updated int
err := db.Conn.QueryRow("UPDATE plans SET archived_at = NOW() WHERE id = $1 RETURNING 1", planId).Scan(&updated)
found := err == nil Defensive patterns
Strategy: fallback
Validate before calling
const plan = await getPlan(planId);
if (!plan) throw new Error('Plan not found before archive call'); Type guard
function isDriverResult(v) { return v !== null && typeof v === 'object' && typeof v.RowsAffected === 'function'; } Try / catch
try { await archivePlan(planId); } catch (e) { if (e.status === 500 && /rows affected/i.test(e.message)) { // driver couldn't report count; verify state and continue
const p = await getPlan(planId); if (p?.archivedAt) return; } throw e; } Prevention
- Prefer RETURNING clauses over RowsAffected when driver support is uncertain
- Pin/verify the Postgres driver version used by the server
- After ambiguous archive errors, re-fetch the plan to confirm actual state
- Add integration tests covering RowsAffected behavior of the chosen driver
When it happens
Trigger: Calling RowsAffected on a driver result that doesn't support it — typically a driver/dialect mismatch, or a connection/driver error surfacing when inspecting the result of the archive UPDATE.
Common situations: Using a driver whose RowsAffected is unimplemented/limited for the statement; a connection reset between Exec and RowsAffected; swapping database drivers without updating handler assumptions.
Related errors
- Error archiving plan:
- error updating plan total replies: %v
- error getting plan: %v
- error setting plan status: %v
- error renaming plan: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/482dfff69fba3c5e.
Report an issue: GitHub.