{"record":{"id":"da5345b7ae247b19","repo":"plandex-ai/plandex","slug":"error-getting-rows-affected-da5345","errorCode":null,"errorMessage":"Error getting rows affected: ","messagePattern":"Error getting rows affected: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/projects.go","lineNumber":216,"sourceCode":"\tif requestBody.Name == \"\" {\n\t\tlog.Println(\"Received empty name field\")\n\t\thttp.Error(w, \"name field is required\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tres, err := db.Conn.Exec(\"UPDATE projects SET name = $1 WHERE id = $2\", requestBody.Name, projectId)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error updating project: %v\\n\", err)\n\t\thttp.Error(w, \"Error updating project: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\trowsAffected, err := res.RowsAffected()\n\n\tif err != nil {\n\t\tlog.Printf(\"Error getting rows affected: %v\\n\", err)\n\t\thttp.Error(w, \"Error getting rows affected: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif rowsAffected == 0 {\n\t\tlog.Printf(\"Project not found: %v\\n\", projectId)\n\t\thttp.Error(w, \"Project not found: \"+projectId, http.StatusNotFound)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully renamed project\", projectId)\n\n}\n","sourceCodeStart":198,"sourceCodeEnd":229,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/projects.go#L198-L229","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the server log for the full RowsAffected error and inspect driver health/connection state.","Upgrade or pin a known-good version of the Postgres driver (lib/pq or pgx).","If using pgx, ensure db.Conn is a *pgx.Conn not a wrapped interface lacking proper RowsAffected support.","Treat transient failures as retryable: wrap the rename in a retry with backoff.","Alternatively skip RowsAffected and use a RETURNING clause to know whether the row was updated."],"exampleFix":"// before\nrowsAffected, err := res.RowsAffected()\nif err != nil {\n    http.Error(w, \"Error getting rows affected: \"+err.Error(), http.StatusInternalServerError)\n    return\n}\n// after\nvar updated bool\nerr := db.Conn.QueryRow(\n    \"UPDATE projects SET name = $1 WHERE id = $2 RETURNING true\",\n    requestBody.Name, projectId,\n).Scan(&updated)\nif errors.Is(err, pgx.ErrNoRows) {\n    http.Error(w, \"Project not found: \"+projectId, http.StatusNotFound)\n    return\n} else if err != nil {\n    http.Error(w, \"Error updating project\", http.StatusInternalServerError)\n    return\n}","handlingStrategy":"retry","validationCode":"// prefer a statement that self-reports: UPDATE ... RETURNING true, avoiding a separate RowsAffected call","typeGuard":null,"tryCatchPattern":"// server-side retry\nvar rowsAffected int64\nfor attempt := 0; attempt < 3; attempt++ {\n    res, err := db.Conn.Exec(\"UPDATE projects SET name = $1 WHERE id = $2\", name, id)\n    if err != nil { time.Sleep(backoff(attempt)); continue }\n    rowsAffected, err = res.RowsAffected()\n    if err == nil { break }\n}\nif rowsAffected == 0 { http.Error(w, \"Project not found\", http.StatusNotFound); return }","preventionTips":["Pin and regularly update the Postgres driver to a known-good version.","Use QueryRow with RETURNING instead of RowsAffected when possible.","Monitor for connection drops between Exec and result reads.","Wrap DB operations in retry middleware for transient errors."],"tags":["database","postgres","driver","http-500"],"backgroundTag":"rows-affected-error","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}