plandex-ai/plandex · error

Error getting rows affected:

Error message

Error getting rows affected: 

What it means

This HTTP 500 response means the UPDATE succeeded but res.RowsAffected() returned an error. The underlying Postgres driver failed to report how many rows the statement affected — usually a driver/connection-level problem after the statement ran. The handler needs this count to distinguish a successful rename from a no-op (project not found).

Source

Thrown at app/server/handlers/projects.go:216

	if requestBody.Name == "" {
		log.Println("Received empty name field")
		http.Error(w, "name field is required", http.StatusBadRequest)
		return
	}

	res, err := db.Conn.Exec("UPDATE projects SET name = $1 WHERE id = $2", requestBody.Name, projectId)

	if err != nil {
		log.Printf("Error updating project: %v\n", err)
		http.Error(w, "Error updating project: "+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.Printf("Project not found: %v\n", projectId)
		http.Error(w, "Project not found: "+projectId, http.StatusNotFound)
		return
	}

	log.Println("Successfully renamed project", projectId)

}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the server log for the full RowsAffected error and inspect driver health/connection state.
  2. Upgrade or pin a known-good version of the Postgres driver (lib/pq or pgx).
  3. If using pgx, ensure db.Conn is a *pgx.Conn not a wrapped interface lacking proper RowsAffected support.
  4. Treat transient failures as retryable: wrap the rename in a retry with backoff.
  5. Alternatively skip RowsAffected and use a RETURNING clause to know whether the row was updated.

Example fix

// before
rowsAffected, err := res.RowsAffected()
if err != nil {
    http.Error(w, "Error getting rows affected: "+err.Error(), http.StatusInternalServerError)
    return
}
// after
var updated bool
err := db.Conn.QueryRow(
    "UPDATE projects SET name = $1 WHERE id = $2 RETURNING true",
    requestBody.Name, projectId,
).Scan(&updated)
if errors.Is(err, pgx.ErrNoRows) {
    http.Error(w, "Project not found: "+projectId, http.StatusNotFound)
    return
} else if err != nil {
    http.Error(w, "Error updating project", http.StatusInternalServerError)
    return
}
Defensive patterns

Strategy: retry

Validate before calling

// prefer a statement that self-reports: UPDATE ... RETURNING true, avoiding a separate RowsAffected call

Try / catch

// server-side retry
var rowsAffected int64
for attempt := 0; attempt < 3; attempt++ {
    res, err := db.Conn.Exec("UPDATE projects SET name = $1 WHERE id = $2", name, id)
    if err != nil { time.Sleep(backoff(attempt)); continue }
    rowsAffected, err = res.RowsAffected()
    if err == nil { break }
}
if rowsAffected == 0 { http.Error(w, "Project not found", http.StatusNotFound); return }

Prevention

When it happens

Trigger: Driver failing to read the command tag from the Postgres response (connection interrupted right after the UPDATE); using a driver/connection wrapper whose RowsAffected is unsupported; rare driver bugs on pooled connections.

Common situations: Flaky network between app and Postgres where the connection drops between Exec and RowsAffected; custom Conn wrapper (interface mismatch) that returns an error for RowsAffected; driver version regression after an upgrade.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/da5345b7ae247b19. Report an issue: GitHub.