plandex-ai/plandex · error
Error reading request body
Error message
Error reading request body
What it means
RewindPlanHandler reads the entire request body with io.ReadAll(r.Body) before decoding the rewind request. If the read fails (connection reset mid-upload, client disconnect, body size/transport error), the handler returns a 500 with 'Error reading request body'. This is a transport-level problem between client and server, not a JSON problem.
Source
Thrown at app/server/handlers/plans_versions.go:104
if auth == nil {
return
}
vars := mux.Vars(r)
planId := vars["planId"]
branch := vars["branch"]
log.Println("planId: ", planId)
if authorizePlan(w, planId, auth) == nil {
return
}
// read the request body
body, err := io.ReadAll(r.Body)
if err != nil {
log.Printf("Error reading request body: %v\n", err)
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
defer r.Body.Close()
var requestBody shared.RewindPlanRequest
if err := json.Unmarshal(body, &requestBody); err != nil {
log.Printf("Error parsing request body: %v\n", err)
http.Error(w, "Error parsing request body", http.StatusBadRequest)
return
}
ctx, cancel := context.WithCancel(r.Context())
err = db.ExecRepoOperation(db.ExecRepoOperationParams{
OrgId: auth.OrgId,
UserId: auth.User.Id,
PlanId: planId,
Branch: branch,View on GitHub (pinned to e2d772072e)
Solutions
- Retry the request; the failure is usually transient.
- Increase proxy/gateway read timeouts and body limits (e.g., nginx proxy_read_timeout, client_max_body_size).
- Ensure the client sends Content-Length or proper chunked encoding and does not abort early.
- Check server logs for the underlying io error to distinguish client disconnects from infra issues.
Example fix
// before curl -X POST $API/plans/rewind -d @big.json --max-time 2 # aborted mid-upload // after curl -X POST $API/plans/rewind -H 'Content-Type: application/json' --data-binary @rewind.json --max-time 30
Defensive patterns
Strategy: retry
Validate before calling
// ensure body is fully available and sized before sending
payload, _ := json.Marshal(rewindReq)
if len(payload) == 0 || len(payload) > maxBodySize {
return errors.New("rewind payload missing or too large")
} Type guard
func bodyReadSucceeded(err error) bool { return err == nil } Try / catch
err := withRetry(3, func() error {
resp, e := http.Post(rewindURL, "application/json", bytes.NewReader(payload))
if e != nil { return e }
if resp.StatusCode == 500 && bodyContains(resp, "Error reading request body") {
return errRetryable // transport glitch; retry
}
return nil
}) Prevention
- Set generous client and proxy timeouts for rewind requests
- Avoid aborting requests mid-upload (respect context deadlines)
- Raise proxy body limits (nginx client_max_body_size, proxy_read_timeout)
- Retry idempotent reads on 500 body-read failures
When it happens
Trigger: io.ReadAll(r.Body) returns an error at plans_versions.go:104 — typically the client closed the connection during upload, a proxy timed out, or the request body stream was interrupted.
Common situations: Flaky networks or aggressive reverse-proxy timeouts (nginx proxy_read_timeout), clients aborting large rewind requests, or HTTP/2 stream resets.
Related errors
- Error reading request body
- token exchange failed - error reading body: %s
- failed to update context: %v
- failed to download the update: %w
- error reading request body: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/3ea879785c324fc7.
Report an issue: GitHub.