{"record":{"id":"16c80f790397f516","repo":"plandex-ai/plandex","slug":"error-marshalling-plan","errorCode":null,"errorMessage":"Error marshalling plan: ","messagePattern":"Error marshalling plan: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_crud.go","lineNumber":152,"sourceCode":"\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tplanId := vars[\"planId\"]\n\n\tlog.Println(\"planId: \", planId)\n\n\tplan := authorizePlan(w, planId, auth)\n\n\tif plan == nil {\n\t\treturn\n\t}\n\n\tbytes, err := json.Marshal(plan)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error marshalling plan: %v\\n\", err)\n\t\thttp.Error(w, \"Error marshalling plan: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Write(bytes)\n}\n\nfunc RenamePlanHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"Received request for RenamePlanHandler\")\n\n\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\tvars := mux.Vars(r)\n\tplanId := vars[\"planId\"]\n\n\tlog.Println(\"planId: \", planId)","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_crud.go#L134-L170","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the server log for the specific json error, which identifies the failing field/type","Fix or remove the faulty custom MarshalJSON on the plan struct or its fields","Ensure the plandex-shared dependency version is consistent (go mod tidy / go get shared@latest)","Add a regression test that marshals a fully populated shared.Plan"],"exampleFix":"// before\nbytes, err := json.Marshal(plan)\nif err != nil { http.Error(w, \"Error marshalling plan: \"+err.Error(), http.StatusInternalServerError); return }\n// after\nbytes, err := json.Marshal(plan.ToApi())\nif err != nil { log.Printf(\"Error marshalling plan: %v\", err); http.Error(w, \"internal error\", http.StatusInternalServerError); return }","handlingStrategy":"try-catch","validationCode":"if plan == nil || plan.Id == \"\" { http.Error(w, \"Not found\", http.StatusNotFound); return }","typeGuard":null,"tryCatchPattern":"bytes, err := json.Marshal(plan)\nif err != nil {\n\tlog.Printf(\"Error marshalling plan: %v\\n\", err)\n\thttp.Error(w, \"Error marshalling plan\", http.StatusInternalServerError)\n\treturn\n}\nw.Write(bytes)","preventionTips":["Test marshalling of fully populated plan fixtures in CI","Audit any custom MarshalJSON on plan types for recursion or panics","Pin a compatible version of the shared types module","Serialize via .ToApi() DTOs rather than raw DB structs"],"tags":["json","serialization","go","server-error"],"backgroundTag":"json-marshall-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}