plandex-ai/plandex · error · http

Error decoding request body

Error message

Error decoding request body

What it means

UpdateSettingsHandler decodes the request body into shared.UpdateSettingsRequest using json.NewDecoder(r.Body).Decode. A decode failure (malformed JSON, wrong types, empty body) triggers a logged message and an HTTP 500 response. Note the semantics: this is really a client-side bad request even though the server replies 500.

Source

Thrown at app/server/handlers/settings.go:105

	vars := mux.Vars(r)
	planId := vars["planId"]
	branch := vars["branch"]

	log.Println("planId: ", planId, "branch: ", branch)

	plan := authorizePlan(w, planId, auth)

	if plan == nil {
		return
	}

	var req shared.UpdateSettingsRequest
	err := json.NewDecoder(r.Body).Decode(&req)

	if err != nil {
		log.Println("Error decoding request body: ", err)
		http.Error(w, "Error decoding request body", http.StatusInternalServerError)
		return
	}

	if req.ModelPackName == "" && req.ModelPack == nil {
		log.Println("No model pack name or model pack provided")
		http.Error(w, "No model pack name or model pack provided", http.StatusBadRequest)
		return
	}

	if req.ModelPackName != "" {
		if mp, builtIn := shared.BuiltInModelPacksByName[req.ModelPackName]; builtIn {
			if os.Getenv("IS_CLOUD") != "" && mp.LocalProvider != "" {
				msg := fmt.Sprintf("Built-in local model pack %s can't be used on Plandex Cloud", req.ModelPackName)
				log.Println(msg)
				http.Error(w, msg, http.StatusUnprocessableEntity)
				return
			}
		}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Send a valid JSON body matching shared.UpdateSettingsRequest (check modelPackName is a string or modelPack an object)
  2. Set Content-Type: application/json on the request
  3. Validate the payload with a JSON linter before sending
  4. If you control the server, return 400 instead of 500 and use http.MaxBytesReader for oversized bodies

Example fix

// before
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
    http.Error(w, "Error decoding request body", http.StatusInternalServerError)
// after
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
    http.Error(w, "Invalid JSON body: "+err.Error(), http.StatusBadRequest)
Defensive patterns

Strategy: validation

Validate before calling

body, err := json.Marshal(shared.UpdateSettingsRequest{ModelPackName: "default"})
if err != nil {
    return err
}
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")

Try / catch

resp, err := client.UpdateSettings(ctx, req)
if err != nil {
    var apiErr *APIError
    if errors.As(err, &apiErr) && apiErr.StatusCode == 500 && strings.Contains(apiErr.Message, "Error decoding request body") {
        // fix payload JSON and resend
    }
    return err
}

Prevention

When it happens

Trigger: Request body is not valid JSON; body is empty; a field has the wrong type (e.g. modelPack as a string instead of object); body already consumed by a prior read; charset/encoding issues in Content-Type.

Common situations: CLI or API client sending truncated or hand-built JSON; missing Content-Type causing client to send form data; proxy/gateway mangling the body; sending JSON with incorrect nesting for UpdateSettingsRequest.

Related errors


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