plandex-ai/plandex · error

Error marshalling plan:

Error message

Error marshalling plan: 

What it means

GetPlanHandler returns this 500 when json.Marshal fails on the fetched plan object. The plan was authorized and loaded, but serialization to JSON for the HTTP response failed. As with other marshal errors this points to a bad custom marshaler or a data-shape bug rather than a user problem.

Source

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

		return
	}

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

	log.Println("planId: ", planId)

	plan := authorizePlan(w, planId, auth)

	if plan == nil {
		return
	}

	bytes, err := json.Marshal(plan)

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

	w.Write(bytes)
}

func RenamePlanHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for RenamePlanHandler")

	auth := Authenticate(w, r, true)
	if auth == nil {
		return
	}

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

	log.Println("planId: ", planId)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the server log for the specific json error, which identifies the failing field/type
  2. Fix or remove the faulty custom MarshalJSON on the plan struct or its fields
  3. Ensure the plandex-shared dependency version is consistent (go mod tidy / go get shared@latest)
  4. Add a regression test that marshals a fully populated shared.Plan

Example fix

// before
bytes, err := json.Marshal(plan)
if err != nil { http.Error(w, "Error marshalling plan: "+err.Error(), http.StatusInternalServerError); return }
// after
bytes, err := json.Marshal(plan.ToApi())
if err != nil { log.Printf("Error marshalling plan: %v", err); http.Error(w, "internal error", http.StatusInternalServerError); return }
Defensive patterns

Strategy: try-catch

Validate before calling

if plan == nil || plan.Id == "" { http.Error(w, "Not found", http.StatusNotFound); return }

Try / catch

bytes, err := json.Marshal(plan)
if err != nil {
	log.Printf("Error marshalling plan: %v\n", err)
	http.Error(w, "Error marshalling plan", http.StatusInternalServerError)
	return
}
w.Write(bytes)

Prevention

When it happens

Trigger: GET plan by id where json.Marshal(plan) errors: the *shared.Plan (or an embedded type) has a MarshalJSON that fails or recurses infinitely; marshal happens on every successful GET so any data-dependent marshal bug triggers it.

Common situations: A field type added to the plan struct with a broken MarshalJSON; a map key type that cannot be serialized (e.g. map[func]T) after a schema change; incompatible shared library version between server and shared module.

Related errors


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