{"record":{"id":"6dacbf8e01c99207","repo":"plandex-ai/plandex","slug":"error-reading-request-body-6dacbf","errorCode":null,"errorMessage":"Error reading request body","messagePattern":"Error reading request body","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/projects.go","lineNumber":29,"sourceCode":"\tshared \"plandex-shared\"\n\n\t\"github.com/gorilla/mux\"\n\t\"github.com/jmoiron/sqlx\"\n)\n\nfunc CreateProjectHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"Received request for CreateProjectHandler\")\n\n\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\t// read the request body\n\tbody, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\tlog.Printf(\"Error reading request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error reading request body\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer r.Body.Close()\n\n\tvar requestBody shared.CreateProjectRequest\n\tif err := json.Unmarshal(body, &requestBody); err != nil {\n\t\tlog.Printf(\"Error parsing request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error parsing request body\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\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\tvar projectId string","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/projects.go#L11-L47","documentation":"CreateProjectHandler reads the raw request body with io.ReadAll before decoding the CreateProjectRequest. A read error produces a 500 with 'Error reading request body'. Like error 1036, this is a transport/stream failure, not a payload-format problem.","triggerScenarios":"io.ReadAll(r.Body) errors at projects.go:29 — client disconnected mid-request, proxy interrupted the upload, or the connection was reset before the body completed.","commonSituations":"Mobile/unstable clients dropping connections, gateway request timeouts, load balancers cutting long requests, or clients sending no body then closing abruptly.","solutions":["Retry the create-project request once the network is stable.","Raise proxy/LB timeouts and body size limits.","Ensure the HTTP client completes the body write (check for early aborts, context cancellations).","Inspect the server log's wrapped io error to pinpoint disconnect vs. infrastructure failure."],"exampleFix":"// before\nfetch(url, {method:'POST', body: JSON.stringify(project), signal: AbortSignal.timeout(500)}) // aborted mid-send\n// after\nfetch(url, {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(project), signal: AbortSignal.timeout(15000)})","handlingStrategy":"retry","validationCode":"// pre-flight: serialize and size-check the create-project payload\npayload, err := json.Marshal(shared.CreateProjectRequest{Name: name})\nif err != nil || len(payload) == 0 { return errors.New(\"empty or invalid create-project payload\") }","typeGuard":"func bodyReadSucceeded(err error) bool { return err == nil }","tryCatchPattern":"err := withRetry(3, func() error {\n    resp, e := postCreateProject(payload)\n    if e != nil { return e }\n    if resp.StatusCode == 500 && bodyContains(resp, \"Error reading request body\") {\n        return errRetryable // connection dropped; retry with backoff\n    }\n    return nil\n})","preventionTips":["Use stable networks/timeouts for project creation calls","Do not cancel the request context while the body is streaming","Configure LB/gateway timeouts above worst-case upload time","Log the server-side wrapped io error to separate client aborts from infra faults"],"tags":["http","go","request-body","network"],"backgroundTag":"request-body-read-failed","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"}