plandex-ai/plandex · error
Error encoding custom provider: %v
Error message
Error encoding custom provider: %v
What it means
GetCustomProviderHandler encodes res.ToApi() into the response with json.NewEncoder(w).Encode; on failure it logs 'Error encoding custom provider' and returns 500. The JSON encoding of a CustomProvider rarely fails on data; the usual cause is the HTTP connection failing while the encoder writes (client gone, connection reset).
Source
Thrown at app/server/handlers/models.go:424
func GetCustomProviderHandler(w http.ResponseWriter, r *http.Request) {
auth := Authenticate(w, r, true)
if auth == nil {
return
}
id := mux.Vars(r)["providerId"]
res, err := db.GetCustomProvider(auth.OrgId, id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = json.NewEncoder(w).Encode(res.ToApi())
if err != nil {
log.Printf("Error encoding custom provider: %v\n", err)
http.Error(w, fmt.Sprintf("Error encoding custom provider: %v", err), http.StatusInternalServerError)
return
}
log.Println("Successfully fetched custom provider")
}
func ListCustomProvidersHandler(w http.ResponseWriter, r *http.Request) {
auth := Authenticate(w, r, true)
if auth == nil {
return
}
if os.Getenv("IS_CLOUD") != "" {
http.Error(w, "Custom model providers are not supported on Plandex Cloud", http.StatusBadRequest)
return
}
list, err := db.ListCustomProviders(auth.OrgId)View on GitHub (pinned to e2d772072e)
Solutions
- Check whether the requesting client actually received anything; a disconnect here is benign — retry the request.
- Review proxy/load-balancer timeout configuration for premature connection closes.
- If reproducible with healthy connections, inspect CustomProvider.ToApi() for newly added unmarshalable fields.
- Marshal to a buffer before writing so encode errors are separated from transport write errors.
Example fix
// before
err = json.NewEncoder(w).Encode(res.ToApi())
if err != nil {
http.Error(w, fmt.Sprintf("Error encoding custom provider: %v", err), http.StatusInternalServerError)
}
// after
buf, err := json.Marshal(res.ToApi())
if err != nil {
http.Error(w, "encoding failed", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(buf) Defensive patterns
Strategy: try-catch
Validate before calling
// Caller: ensure a live connection and a non-cancelled context before requesting
if r.Context().Err() != nil { return }
req, _ := http.NewRequestWithContext(r.Context(), "GET", providerURL, nil) Try / catch
if err := json.NewEncoder(w).Encode(res.ToApi()); err != nil {
log.Printf("Error encoding custom provider: %v", err)
return // headers may already be sent; do not attempt http.Error after a partial write
} Prevention
- Marshal to a buffer first, then a single w.Write, to isolate encode vs transport errors
- Treat post-header write errors as transport noise, not 500-worthy server bugs
- Configure proxies with timeouts longer than the handler's worst-case latency
- Keep CustomProvider.ToApi() free of unmarshalable types
When it happens
Trigger: GET custom provider where the client disconnects or the transport errors while the JSON body is written to the ResponseWriter.
Common situations: Client aborts the request right after it is issued; proxy timeout kills the upstream connection during the write; network drop on mobile clients.
Related errors
- Error encoding custom model: %v
- Error encoding custom models: %v
- token exchange failed - error reading body: %s
- failed to update context: %v
- failed to download the update: %w
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/eda091a47391e64e.
Report an issue: GitHub.