{"record":{"id":"d1bf18c497d9d32e","repo":"plandex-ai/plandex","slug":"error-marshalling-response-d1bf18","errorCode":null,"errorMessage":"Error marshalling response: ","messagePattern":"Error marshalling response: ","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/context_helper.go","lineNumber":294,"sourceCode":"\n\t\tlog.Printf(\"[ContextHelper] Committing changes to branch %s completed successfully\", branchName)\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tlog.Printf(\"Error loading contexts: %v\\n\", err)\n\t\thttp.Error(w, \"Error loading contexts: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn nil, nil\n\t}\n\n\tif loadRes.MaxTokensExceeded {\n\t\tlog.Printf(\"The total number of tokens (%d) exceeds the maximum allowed (%d)\", loadRes.TotalTokens, loadRes.MaxTokens)\n\t\tbytes, err := json.Marshal(loadRes)\n\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: \"+err.Error(), http.StatusInternalServerError)\n\t\t\treturn nil, nil\n\t\t}\n\n\t\tw.Write(bytes)\n\t\treturn nil, nil\n\t}\n\n\treturn loadRes, dbContexts\n}\n","sourceCodeStart":276,"sourceCodeEnd":304,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/context_helper.go#L276-L304","documentation":"When the load succeeds but the accumulated context exceeds the model's token budget, loadRes.MaxTokensExceeded is true and loadRes is marshalled to return the token accounting to the client. A json.Marshal failure on that response — practically impossible for this plain struct — returns HTTP 500 with 'Error marshalling response: ' + err.","triggerScenarios":"loadRes.MaxTokensExceeded is true and json.Marshal(loadRes) returns an error (unsupported type in the response struct, custom MarshalJSON panicking/err-ing).","commonSituations":"Only from code-level changes: a custom type added to LoadContextResponse with a faulty MarshalJSON, or an incompatible shared-library version mismatch after a partial deploy.","solutions":["Inspect the logged marshal error to identify the offending field type in LoadContextResponse","Fix or remove the custom MarshalJSON on the offending type in plandex-shared","Redeploy server and shared library from the same version so the struct definitions match"],"exampleFix":"// before\ntype Bad struct{ Fn func() } // makes Marshal fail\n// after\ntype OK struct{ TotalTokens int `json:\"totalTokens\"`; MaxTokens int `json:\"maxTokens\"` } // marshalable fields only","handlingStrategy":"type-guard","validationCode":"// effectively unreachable; ensure server and shared lib versions match\nif buildVersion != shared.Version {\n    return fmt.Errorf(\"server %s and shared lib %s mismatch\", buildVersion, shared.Version)\n}","typeGuard":"func marshalable(v any) bool {\n    b, err := json.Marshal(v)\n    return err == nil && b != nil\n}\n// if !marshalable(loadRes) { log and fail fast before writing response }","tryCatchPattern":"bytes, err := json.Marshal(loadRes)\nif err != nil {\n    // log the field/type that failed and return a static fallback payload\n    bytes, _ = json.Marshal(fallbackTokenSummary(loadRes))\n}","preventionTips":["Keep LoadContextResponse fields JSON-serializable (no funcs/channels)","Deploy server and plandex-shared from the same commit","Add a round-trip json.Marshal test for response structs"],"tags":["http-500","json","serialization","plandex"],"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-14T05:17:10.506Z"}