plandex-ai/plandex · error
Error parsing request body
Error message
Error parsing request body
What it means
After reading the body, TellPlanHandler unmarshals it into shared.TellPlanRequest with json.Unmarshal. Malformed JSON (or a type mismatch with the struct fields) triggers this handler, which responds 400 'Error parsing request body' and reports the error asynchronously. It indicates the client sent a body that is not valid JSON matching TellPlanRequest.
Source
Thrown at app/server/handlers/plans_exec.go:65
}
body, err := io.ReadAll(r.Body)
if err != nil {
log.Printf("Error reading request body: %v\n", err)
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error reading request body: %v", err))
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
defer func() {
log.Println("Closing request body")
r.Body.Close()
}()
var requestBody shared.TellPlanRequest
if err := json.Unmarshal(body, &requestBody); err != nil {
log.Printf("Error parsing request body: %v\n", err)
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error parsing request body: %v", err))
http.Error(w, "Error parsing request body", http.StatusBadRequest)
return
}
_, apiErr := hooks.ExecHook(hooks.WillTellPlan, hooks.HookParams{
Auth: auth,
Plan: plan,
})
if apiErr != nil {
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error executing will tell plan hook: %v", apiErr))
writeApiError(w, *apiErr)
return
}
orgUserConfig, err := db.GetOrgUserConfig(auth.User.Id, auth.OrgId)
if err != nil {
log.Printf("Error getting org user config: %v\n", err)
http.Error(w, "Error getting org user config", http.StatusInternalServerError)
returnView on GitHub (pinned to e2d772072e)
Solutions
- Validate the JSON body locally with `echo '<payload>' | jq .` or json.Unmarshal in a test before sending.
- Upgrade the Plandex CLI to match the server's shared.TellPlanRequest schema (field names/types changed across versions).
- Check the server log for the exact json.Unmarshal message (e.g. 'invalid character', 'cannot unmarshal ... into Go value') to pinpoint the offending field.
- Send Content-Type: application/json and serialize the body with a JSON encoder rather than string concatenation.
Example fix
// before: hand-built JSON with unquoted key
body := []byte(`{apiKeys: {"OPENAI_API_KEY": "sk-..."}}`)
// after: struct + json.Marshal guarantees valid JSON
req := shared.TellPlanRequest{ApiKeys: map[string]string{"OPENAI_API_KEY": "sk-..."}}
body, _ := json.Marshal(req) Defensive patterns
Strategy: validation
Validate before calling
// validate payload before sending
var probe map[string]any
if err := json.Unmarshal(payload, &probe); err != nil {
return fmt.Errorf("invalid JSON: %w", err)
} Type guard
func isValidTellPlanRequest(b []byte) bool {
var req shared.TellPlanRequest
return json.Unmarshal(b, &req) == nil
} Try / catch
if err := json.Unmarshal(payload, &req); err != nil {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
return fmt.Errorf("bad JSON at offset %d: %w", syntaxErr.Offset, err)
}
return err
} Prevention
- Always serialize with json.Marshal from a typed struct, never string concatenation.
- Keep CLI and server on matching versions so TellPlanRequest fields align.
- Send Content-Type: application/json.
- Lint hand-written curl/CI payloads with jq before deployment.
When it happens
Trigger: POST to the tell-plan endpoint with: syntactically invalid JSON, an empty body, wrong types for fields (e.g. ApiKeys as string instead of map), or a JSON array where an object is expected.
Common situations: Older CLI version sending a deprecated request schema; manual curl with unquoted/missing fields; string interpolation corrupting the payload; missing Content-Type combined with hand-built JSON.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- error parsing request body: %v
- Error decoding request: %v
- Has duplicates:
- Provider name is required
- Model id is required
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f1919c9ae9b7b585.
Report an issue: GitHub.