plandex-ai/plandex · error
Error marshalling contexts:
Error message
Error marshalling contexts:
What it means
After converting db contexts to API contexts, ListContextHandler json.Marshal's the []*shared.Context slice. Marshal only fails here if a Context field holds an unsupported type (e.g. channel, func, or cyclic data). In practice this is nearly impossible with fixed DB-backed structs, so the error signals an unexpected data/model problem, returned as HTTP 500.
Source
Thrown at app/server/handlers/plans_context.go:73
})
if err != nil {
log.Printf("Error getting contexts: %v\n", err)
http.Error(w, "Error getting contexts: "+err.Error(), http.StatusInternalServerError)
return
}
var apiContexts []*shared.Context
for _, dbContext := range dbContexts {
apiContexts = append(apiContexts, dbContext.ToApi())
}
bytes, err := json.Marshal(apiContexts)
if err != nil {
log.Printf("Error marshalling contexts: %v\n", err)
http.Error(w, "Error marshalling contexts: "+err.Error(), http.StatusInternalServerError)
return
}
w.Write(bytes)
}
func GetContextBodyHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Received request for GetContextBodyHandler")
auth := Authenticate(w, r, true)
if auth == nil {
return
}
vars := mux.Vars(r)
planId := vars["planId"]
branch := vars["branch"]
contextId := vars["contextId"]View on GitHub (pinned to e2d772072e)
Solutions
- Read err.Error() — Go names the exact unsupported type and struct field
- Check recent changes to shared.Context / db.Context.ToApi() for unserializable fields (func, chan, cycles)
- Add json:"-" tags to fields that must not be serialized, or give them custom MarshalJSON
- Rebuild/redeploy from a known-good release to confirm it's a code-level issue
Example fix
// before
type Context struct {
loader func() error // unsupported by json.Marshal
...
}
// after
type Context struct {
loader func() error `json:"-"`
...
} Defensive patterns
Strategy: type-guard
Validate before calling
func marshalable(v any) bool {
b, err := json.Marshal(v)
return err == nil && b != nil
} Type guard
func hasUnsupportedFields(v reflect.Value, seen map[uintptr]bool) bool {
switch v.Kind() {
case reflect.Chan, reflect.Func:
return true
case reflect.Ptr, reflect.Map:
if v.IsNil() { return false }
if seen[v.Pointer()] { return true }
seen[v.Pointer()] = true
defer delete(seen, v.Pointer())
}
switch v.Kind() {
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
if hasUnsupportedFields(v.Field(i), seen) { return true }
}
case reflect.Slice, reflect.Array:
for i := 0; i < v.Len(); i++ {
if hasUnsupportedFields(v.Index(i), seen) { return true }
}
}
return false
} Try / catch
bytes, err := json.Marshal(apiContexts)
if err != nil {
log.Printf("Error marshalling contexts: %v", err)
http.Error(w, "Error marshalling contexts", http.StatusInternalServerError)
return
} Prevention
- Never add chan/func/cyclic fields to API response structs, or tag them json:"-"
- Add a CI test that marshals representative response values
- Keep shared API types in sync between client and server builds
When it happens
Trigger: json.Marshal(apiContexts) returns an error — an unsupported value in shared.Context (channel/func/cycle) introduced by a code or model change.
Common situations: A recent code change added an unserializable field to shared.Context or db.Context.ToApi(); custom build with modified model types.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Error marshalling invites:
- Error marshalling response:
- Error marshalling plans:
- Error marshalling response:
- Error marshalling projects:
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/893d7cfae35d350a.
Report an issue: GitHub.