{"record":{"id":"302aa2c82719de42","repo":"plandex-ai/plandex","slug":"error-reading-request-body-302aa2","errorCode":null,"errorMessage":"Error reading request body","messagePattern":"Error reading request body","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/branches.go","lineNumber":102,"sourceCode":"\tif auth == nil {\n\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tplanId := vars[\"planId\"]\n\tbranch := vars[\"branch\"]\n\n\tlog.Println(\"planId: \", planId)\n\n\tplan := authorizePlan(w, planId, auth)\n\tif plan == nil {\n\t\treturn\n\t}\n\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 func() {\n\t\tlog.Println(\"Closing request body\")\n\t\tr.Body.Close()\n\t}()\n\n\tvar req shared.CreateBranchRequest\n\tif err := json.Unmarshal(body, &req); 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\tparentBranch, err := db.GetDbBranch(planId, branch)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error getting parent branch: %v\\n\", err)","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/branches.go#L84-L120","documentation":"CreateBranchHandler reads the raw request body with io.ReadAll(r.Body) and returns HTTP 500 'Error reading request body' if the read fails. This means the handler never received a complete body from the transport — the failure is at the connection/request layer, before JSON parsing. Note the message intentionally omits err.Error() from the response.","triggerScenarios":"POST to the create-branch endpoint when the client disconnects mid-upload, the request times out at a proxy, the body exceeds a server/proxy size limit and the connection is cut, or malformed chunked transfer encoding aborts the stream.","commonSituations":"Flaky network or client timeout while POSTing; a reverse proxy (nginx) buffering limit (client_max_body_size) closing the connection; a load balancer cutting idle uploads.","solutions":["Check that the client sends Content-Length or proper chunked encoding and completes the upload","Raise proxy/body size limits if the request is large (e.g. nginx client_max_body_size)","Increase client/proxy timeouts and retry on transient network failures"],"exampleFix":"// before\nresp, err := http.Post(url, \"application/json\", brokenReader)\n// after\nbody, _ := json.Marshal(req)\nresp, err := http.Post(url, \"application/json\", bytes.NewReader(body)) // complete, sized body","handlingStrategy":"retry","validationCode":"// client: send a fully buffered, sized body\nbody, err := json.Marshal(req)\nif err != nil { return err }\nhttpReq, _ := http.NewRequest(\"POST\", url, bytes.NewReader(body))\nhttpReq.ContentLength = int64(len(body))","typeGuard":null,"tryCatchPattern":"// retry transient network failures\nresp, err := client.Do(httpReq)\nif err != nil {\n    return fmt.Errorf(\"upload failed, retry: %w\", err)\n}","preventionTips":["Always send complete buffered bodies (bytes.Reader) rather than streaming readers that can fail","Set Content-Length explicitly","Keep request bodies small; don't hit proxy size limits","Configure reasonable client and proxy timeouts"],"tags":["http","request-body","network","io"],"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"}