plandex-ai/plandex · error
Error parsing request body
Error message
Error parsing request body
What it means
After successfully reading the body, RewindPlanHandler unmarshals it into shared.RewindPlanRequest. Invalid JSON yields a 400 with 'Error parsing request body'. The server read the bytes fine, but they are not a valid RewindPlanRequest JSON document.
Source
Thrown at app/server/handlers/plans_versions.go:112
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,
Reason: "rewind plan",
Scope: db.LockScopeWrite,
Ctx: ctx,
CancelFn: cancel,
}, func(repo *db.GitRepo) error {
return repo.GitRewindToSha(branch, requestBody.Sha)
})
View on GitHub (pinned to e2d772072e)
Solutions
- Validate the payload is well-formed JSON (jq . body.json).
- Match the exact field names/types of shared.RewindPlanRequest (check the version your server deploys).
- Send header 'Content-Type: application/json'.
- Log/echo the parse error client-side during development to see the exact offset.
Example fix
// before
curl -X POST $API/plans/rewind -d 'planId=abc&commit=def' // form-encoded, not JSON
// after
curl -X POST $API/plans/rewind -H 'Content-Type: application/json' -d '{"planId":"abc","commit":"def"}' Defensive patterns
Strategy: validation
Validate before calling
// validate JSON shape before sending
payload, err := json.Marshal(shared.RewindPlanRequest{PlanId: planId, Commit: commit})
if err != nil { return err }
var check shared.RewindPlanRequest
if err := json.Unmarshal(payload, &check); err != nil {
return fmt.Errorf("payload does not round-trip as RewindPlanRequest: %w", err)
} Type guard
func isValidRewindRequest(b []byte) bool {
var req shared.RewindPlanRequest
return json.Unmarshal(b, &req) == nil
} Try / catch
resp, err := postJSON(rewindURL, payload)
if err != nil {
if resp != nil && resp.StatusCode == 400 && bodyContains(resp, "Error parsing request body") {
return fmt.Errorf("rewind payload malformed: send JSON matching shared.RewindPlanRequest")
}
return err
} Prevention
- Always send Content-Type: application/json
- Validate payloads with a JSON schema or round-trip unmarshal in tests
- Keep client structs in sync with shared.RewindPlanRequest field names/types
- Never send form-encoded or HTML content to JSON API routes
When it happens
Trigger: json.Unmarshal(body, &requestBody) fails at plans_versions.go:112 — malformed JSON, wrong Content-Type payload, or fields with types that do not match shared.RewindPlanRequest (e.g., string where an int is expected).
Common situations: Sending form data or plain text instead of JSON, missing quotes/trailing commas from hand-built payloads, SDK version drift where RewindPlanRequest fields were renamed or retyped.
Related errors
- Error parsing request body
- error parsing request body: %v
- Error marshalling response
- Error decoding request: %v
- File %s is too large: %d (max %d)
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/534e6f8a8640b7b3.
Report an issue: GitHub.