plandex-ai/plandex · error
Error marshalling plan convo:
Error message
Error marshalling plan convo:
What it means
ListConvoHandler returns this 500 when json.Marshal fails to serialize the []*shared.ConvoMessage slice after the convo was fetched successfully. Like any Marshal failure this points to unsupported field types or a failing custom MarshalJSON, which should not occur with normal ConvoMessage data — it usually means a schema/code change introduced something unserializable.
Source
Thrown at app/server/handlers/plans_convo.go:72
return nil
})
if err != nil {
log.Println("Error getting plan convo: ", err)
http.Error(w, "Error getting plan convo: "+err.Error(), http.StatusInternalServerError)
return
}
apiConvoMessages := make([]*shared.ConvoMessage, len(convoMessages))
for i, convoMessage := range convoMessages {
apiConvoMessages[i] = convoMessage.ToApi()
}
bytes, err := json.Marshal(apiConvoMessages)
if err != nil {
log.Println("Error marshalling plan convo: ", err)
http.Error(w, "Error marshalling plan convo: "+err.Error(), http.StatusInternalServerError)
return
}
log.Println("Successfully processed request for ListConvoHandler")
w.Write(bytes)
}
func GetPlanStatusHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Received a request for GetPlanStatusHandler")
auth := Authenticate(w, r, true)
if auth == nil {
return
}
vars := mux.Vars(r)
planId := vars["planId"]View on GitHub (pinned to e2d772072e)
Solutions
- Check the server log for the marshal error detail
- Inspect shared.ConvoMessage and ToApi() for newly added unsupported field types
- Add a regression test marshalling a real ConvoMessage
- If a field is problematic, mark it json:"-" or convert it to a serializable representation
Example fix
// before CreatedAt customTime // type with failing MarshalJSON // after CreatedAt time.Time `json:"createdAt"` // use standard time.Time
Defensive patterns
Strategy: try-catch
Type guard
function isConvoMessageSerializable(m) {
return typeof m === 'object' && m !== null
&& typeof m.id === 'string'
&& (typeof m.text === 'string' || m.text == null);
} Try / catch
try {
const convo = await listPlanConvo(planId, branch);
} catch (e) {
if (/Error marshalling plan convo/.test(e.message)) {
log.error('Server-side serialization defect in ConvoMessage — report to maintainers');
}
throw e;
} Prevention
- Keep shared.ConvoMessage fields JSON-serializable
- Add regression tests marshalling real convo messages
- Never attach runtime-only handles (channels, funcs) to API models
- Validate ToApi() output shapes in CI
When it happens
Trigger: json.Marshal(apiConvoMessages) errors — only realistic if ConvoMessage or its ToApi() output gains an unsupported type (channel, func, cyclic reference) or a field's MarshalJSON returns an error.
Common situations: Recent change to shared.ConvoMessage added a non-serializable field or a custom marshaller that errors; corrupted data feeding a cyclic pointer.
Related errors
- Error marshalling branches:
- Error marshalling response:
- Error marshalling invites:
- Error marshalling response
- Error marshalling contexts:
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/4166fea87e9604f1.
Report an issue: GitHub.