plandex-ai/plandex · warning

Error parsing request body

Error message

Error parsing request body

What it means

CreatePlanHandler returns this 400 Bad Request when json.Unmarshal fails to parse the request body into shared.CreatePlanRequest. The body arrived but is not valid JSON, is empty, or has fields whose types do not match the struct (e.g. name as a number). This is a client-side payload problem by design.

Source

Thrown at app/server/handlers/plans_crud.go:63

	_, apiErr := hooks.ExecHook(hooks.WillCreatePlan, hooks.HookParams{Auth: auth})
	if apiErr != nil {
		writeApiError(w, *apiErr)
		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.CreatePlanRequest
	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
	}

	name := requestBody.Name
	if name == "" {
		name = "draft"
	}

	if name == "draft" {
		// delete any existing draft plans
		err = db.DeleteDraftPlans(auth.OrgId, projectId, auth.User.Id)

		if err != nil {
			log.Printf("Error deleting draft plans: %v\n", err)
			http.Error(w, "Error deleting draft plans: "+err.Error(), http.StatusInternalServerError)
			return
		}
	} else {

View on GitHub (pinned to e2d772072e)

Solutions

  1. Validate the request body is well-formed JSON matching CreatePlanRequest ({"name":"..."})
  2. Send header Content-Type: application/json
  3. Check that the name field is a JSON string, not a number or object
  4. Test the exact payload with a JSON linter or jq before sending
  5. Confirm client SDK/API version matches the server's expected CreatePlanRequest schema

Example fix

// before
curl -X POST $URL/plans -d name=myplan
// after
curl -X POST $URL/plans -H 'Content-Type: application/json' -d '{"name":"myplan"}'
Defensive patterns

Strategy: validation

Validate before calling

function validateCreatePlanRequest(body) {
  const parsed = JSON.parse(body); // throws SyntaxError on invalid JSON before hitting the API
  if (parsed.name !== undefined && typeof parsed.name !== 'string') {
    throw new Error('name must be a string');
  }
  return parsed;
}

Type guard

function isCreatePlanRequest(v) {
  return typeof v === 'object' && v !== null
    && (v.name === undefined || typeof v.name === 'string');
}

Try / catch

try {
  await createPlan(projectId, name);
} catch (e) {
  if (/Error parsing request body/.test(e.message)) {
    console.error('Invalid JSON payload sent to create-plan:', {name});
  }
  throw e;
}

Prevention

When it happens

Trigger: POST create-plan with an empty body, invalid JSON syntax (trailing commas, unquoted keys), wrong Content-Type leading to form-encoded data being sent, or a JSON body where "name" is not a string.

Common situations: Automation scripts sending form data instead of JSON; missing Content-Type header plus non-JSON body; hand-written curl with quoting/escaping mistakes; API version drift where clients send a schema that no longer matches CreatePlanRequest.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/249572a193a6dadd. Report an issue: GitHub.