{"record":{"id":"f488fe64acb840c6","repo":"plandex-ai/plandex","slug":"error-marshalling-response-f488fe","errorCode":null,"errorMessage":"Error marshalling response","messagePattern":"Error marshalling response","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/plans_exec.go","lineNumber":518,"sourceCode":"\t\t\tbranchName: branch,\n\t\t\tautoLoaded: true,\n\t\t})\n\t}\n\n\tif res == nil {\n\t\t// the client will treat this as a no-op\n\t\tmarkdownRes := shared.LoadContextResponse{\n\t\t\tTokensAdded:       0,\n\t\t\tTotalTokens:       0,\n\t\t\tMaxTokensExceeded: false,\n\t\t\tMaxTokens:         0,\n\t\t\tMsg:               \"\",\n\t\t}\n\n\t\tbytes, err := json.Marshal(markdownRes)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Error marshalling response: %v\\n\", err)\n\t\t\thttp.Error(w, \"Error marshalling response\", http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tw.Write(bytes)\n\t\treturn\n\t}\n\n\tlog.Println(\"AutoLoadContextHandler - updating active plan\")\n\n\tmodelPlan.UpdateActivePlan(planId, branch, func(activePlan *types.ActivePlan) {\n\t\tif activePlan == nil {\n\t\t\tlog.Println(\"Active plan is nil\")\n\t\t\thttp.Error(w, \"Active plan is nil\", http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tactivePlan.Contexts = append(activePlan.Contexts, dbContexts...)\n\t\tfor _, dbContext := range dbContexts {\n\t\t\tactivePlan.ContextsByPath[dbContext.FilePath] = dbContext","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_exec.go#L500-L536","documentation":"AutoLoadContextHandler builds a markdown response struct and serializes it with json.Marshal before writing it to the HTTP response. If marshaling fails (e.g., an unsupported type like a channel, func, or a cyclic data structure inside the response), it logs the underlying error and returns a 500 with the plain-text body 'Error marshalling response'. This indicates a server-side bug in response construction, not a client problem.","triggerScenarios":"The markdownRes struct built by AutoLoadContextHandler contains a value json.Marshal cannot encode (chan, func, complex number, or a cyclic reference), so json.Marshal returns an error at plans_exec.go:518.","commonSituations":"A developer adds a field to the response struct whose type is not JSON-serializable, or populates a map/pointer chain that creates a cycle (e.g., a plan referencing itself). Also seen after upgrading a dependency field to a custom type without MarshalJSON.","solutions":["Check the server log line 'Error marshalling response: <err>' to identify the offending field and type.","Remove or replace non-serializable fields (chan/func/cyclic pointers) in the response struct with serializable equivalents (ids, copied data).","Assign json:\"-\" to internal fields that should never be serialized.","Add a unit test that marshals the response struct with representative data to catch regressions."],"exampleFix":"// before\nbytes, err := json.Marshal(markdownRes) // fails: markdownRes.Plan has cyclic pointer\n// after\ntype markdownResponse struct {\n    PlanID string `json:\"planId\"`\n    Content string `json:\"content\"`\n    // cyclic/internal fields removed or tagged `json:\"-\"`\n}\nbytes, err := json.Marshal(markdownRes)","handlingStrategy":"try-catch","validationCode":"// Go client: nothing to pre-validate; ensure server response struct is marshal-tested\nfunc TestMarkdownResponseMarshalable(t *testing.T) {\n    if _, err := json.Marshal(shared.MarkdownResponse{}); err != nil {\n        t.Fatalf(\"response not marshalable: %v\", err)\n    }\n}","typeGuard":"func isMarshalable(v any) bool { _, err := json.Marshal(v); return err == nil }","tryCatchPattern":"resp, err := http.Post(url, \"application/json\", body)\nif err != nil { return err }\nif resp.StatusCode == http.StatusInternalServerError {\n    b, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(b), \"Error marshalling response\") {\n        return fmt.Errorf(\"server serialization bug (1030): %s\", b)\n    }\n}","preventionTips":["Never put chan/func/cyclic pointers in API response structs","Tag internal fields json:\"-\"","Add marshal smoke tests for all response types","Map server errors by status code + body, not just status code"],"tags":["http","json","go","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}