plandex-ai/plandex · error

Error marshalling response:

Error message

Error marshalling response: 

What it means

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.

Source

Thrown at app/server/handlers/context_helper.go:294

		log.Printf("[ContextHelper] Committing changes to branch %s completed successfully", branchName)

		return nil
	})

	if err != nil {
		log.Printf("Error loading contexts: %v\n", err)
		http.Error(w, "Error loading contexts: "+err.Error(), http.StatusInternalServerError)
		return nil, nil
	}

	if loadRes.MaxTokensExceeded {
		log.Printf("The total number of tokens (%d) exceeds the maximum allowed (%d)", loadRes.TotalTokens, loadRes.MaxTokens)
		bytes, err := json.Marshal(loadRes)

		if err != nil {
			log.Printf("Error marshalling response: %v\n", err)
			http.Error(w, "Error marshalling response: "+err.Error(), http.StatusInternalServerError)
			return nil, nil
		}

		w.Write(bytes)
		return nil, nil
	}

	return loadRes, dbContexts
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the logged marshal error to identify the offending field type in LoadContextResponse
  2. Fix or remove the custom MarshalJSON on the offending type in plandex-shared
  3. Redeploy server and shared library from the same version so the struct definitions match

Example fix

// before
type Bad struct{ Fn func() } // makes Marshal fail
// after
type OK struct{ TotalTokens int `json:"totalTokens"`; MaxTokens int `json:"maxTokens"` } // marshalable fields only
Defensive patterns

Strategy: type-guard

Validate before calling

// effectively unreachable; ensure server and shared lib versions match
if buildVersion != shared.Version {
    return fmt.Errorf("server %s and shared lib %s mismatch", buildVersion, shared.Version)
}

Type guard

func marshalable(v any) bool {
    b, err := json.Marshal(v)
    return err == nil && b != nil
}
// if !marshalable(loadRes) { log and fail fast before writing response }

Try / catch

bytes, err := json.Marshal(loadRes)
if err != nil {
    // log the field/type that failed and return a static fallback payload
    bytes, _ = json.Marshal(fallbackTokenSummary(loadRes))
}

Prevention

When it happens

Trigger: loadRes.MaxTokensExceeded is true and json.Marshal(loadRes) returns an error (unsupported type in the response struct, custom MarshalJSON panicking/err-ing).

Common situations: 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.

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/d1bf18c497d9d32e. Report an issue: GitHub.