{"record":{"id":"d116f893853f983b","repo":"plandex-ai/plandex","slug":"error-encoding-custom-model-v","errorCode":null,"errorMessage":"Error encoding custom model: %v","messagePattern":"Error encoding custom model: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/handlers/models.go","lineNumber":366,"sourceCode":"\n\tid := mux.Vars(r)[\"modelId\"]\n\n\tres, err := db.GetCustomModel(auth.OrgId, id)\n\tif err != nil {\n\t\tlog.Printf(\"Error fetching custom model: %v\\n\", err)\n\t\thttp.Error(w, \"Failed to fetch custom model: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif res == nil {\n\t\thttp.Error(w, \"Custom model not found\", http.StatusNotFound)\n\t\treturn\n\t}\n\n\terr = json.NewEncoder(w).Encode(res.ToApi())\n\tif err != nil {\n\t\tlog.Printf(\"Error encoding custom model: %v\\n\", err)\n\t\thttp.Error(w, fmt.Sprintf(\"Error encoding custom model: %v\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tlog.Println(\"Successfully fetched custom model\")\n}\n\nfunc ListCustomModelsHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"Received request for ListCustomModelsHandler\")\n\n\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\tif !requireMinClientVersion(w, r, CustomModelsMinClientVersion) {\n\t\treturn\n\t}\n","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/models.go#L348-L384","documentation":"GetCustomModelHandler writes the fetched custom model to the HTTP response via json.NewEncoder(w).Encode(res.ToApi()). If encoding fails — the response writer has broken/failed (client disconnected, connection reset) or the value cannot be marshaled — the handler logs 'Error encoding custom model' and returns 500 with the same message. In practice this is almost always a broken HTTP pipe, not a data problem.","triggerScenarios":"Client disconnects or the connection is reset mid-response while json.Encoder writes the GET custom model body; or writing to w returns an error for any transport reason.","commonSituations":"Client cancels the request or times out before the body is written; reverse proxy/load balancer closes an upstream connection; mobile client drops network during response.","solutions":["Check client-side logs: the request was likely aborted by the caller — retry with a stable connection.","Verify any reverse proxy (nginx, ALB) timeout/read-buffer settings are not closing the connection mid-write.","If it persists with a live client, inspect CustomModel.ToApi() output for unmarshalable values (channels, funcs, invalid UTF-8) added in recent changes.","Ensure the handler is not writing after the response has already been partially committed elsewhere."],"exampleFix":"// before\nerr = json.NewEncoder(w).Encode(res.ToApi())\nif err != nil {\n    http.Error(w, fmt.Sprintf(\"Error encoding custom model: %v\", err), http.StatusInternalServerError)\n}\n// after\nbuf, err := json.Marshal(res.ToApi())\nif err != nil {\n    http.Error(w, \"encoding failed\", http.StatusInternalServerError)\n    return\n}\nw.Header().Set(\"Content-Type\", \"application/json\")\nw.Write(buf) // encode to buffer first; transport errors on w are not client-fixable","handlingStrategy":"try-catch","validationCode":"// Go: verify the request context is still alive before doing work\nif r.Context().Err() != nil { return } // client already gone; skip the DB/encode work","typeGuard":null,"tryCatchPattern":"if err := json.NewEncoder(w).Encode(res.ToApi()); err != nil {\n    // after headers are sent you cannot change the status; log and return\n    log.Printf(\"encode/transport error: %v\", err)\n    return\n}","preventionTips":["Marshal to a buffer with json.Marshal first, then write once, so data errors differ from transport errors","Set Content-Type and status before the first write so errors are not half-committed","Check r.Context().Err() before expensive work to skip aborted requests","Keep ToApi() outputs JSON-safe: no channels, funcs, or cycles"],"tags":["go","http","json-encoding","network"],"backgroundTag":"http-response-write-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"}