googleapis/mcp-toolbox · error
failed to marshal payload: %w
Error message
failed to marshal payload: %w
What it means
getStream marshals the Conversational Analytics API request payload (CAPayload) to JSON before sending the POST. This error wraps any failure from json.Marshal of that payload. In practice this is rare because CAPayload contains only JSON-serializable fields; it indicates the payload structure became non-marshalable (e.g. custom types with unsupported fields).
Source
Thrown at internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go:272
// getStream wraps network errors or non-200 responses
return nil, util.NewClientServerError("failed to get response from conversational analytics API", http.StatusInternalServerError, err)
}
return response, nil
}
func (t Tool) RequiresClientAuthorization(source sources.Source) (bool, error) {
s, ok := source.(compatibleSource)
if !ok {
return false, fmt.Errorf("invalid source for %q tool: source %q is not a compatible type", t.Cfg.Type, t.Cfg.Source)
}
return s.UseClientAuthorization(), nil
}
func getStream(client *http.Client, url string, payload CAPayload, headers map[string]string, maxRows int) (string, error) {
payloadBytes, err := json.Marshal(payload)
if err != nil {
return "", fmt.Errorf("failed to marshal payload: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
if err != nil {
return "", fmt.Errorf("failed to create request: %w", err)
}
for k, v := range headers {
req.Header.Set(k, v)
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Check for local modifications or forks that added non-JSON-serializable fields to CAPayload/Message and fix their types.
- Ensure the user text and table references passed to Invoke contain no unsupported characters/types by logging the payload before marshaling.
- Rebuild against the upstream version of the toolbox to rule out local drift, then retry Invoke.
Example fix
// before: cyclic/unsupported field in payload
type CAPayload struct { Messages []Message; Callback func() }
// after: keep payload JSON-only
type CAPayload struct { Messages []Message `json:"messages"`; InlineContext InlineContext `json:"inlineContext"`; ClientIdEnum string `json:"clientIdEnum"` } Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := json.Marshal(payload); err != nil {
return fmt.Errorf("payload not serializable: %w", err)
} Try / catch
result, err := tool.Invoke(ctx, params)
if err != nil && strings.Contains(err.Error(), "failed to marshal payload") {
log.Printf("payload construction bug: %v", err)
return fmt.Errorf("internal payload error: %w", err)
} Prevention
- Keep CAPayload limited to JSON-serializable field types.
- Add a unit test that marshals a fully populated CAPayload.
- Avoid injecting untyped/any values into request structs.
When it happens
Trigger: Calling Invoke on the bigquery-conversational-analytics tool when the constructed CAPayload (messages, inlineContext, clientIdEnum) cannot be serialized by encoding/json — e.g. a corrupted/modified payload type containing channels, funcs, or cycles.
Common situations: Custom forks that added unsupported field types to CAPayload or Message; Go version/library changes changing marshal behavior; transient logic bugs injecting nil or cyclic data into the payload.
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 message: %w
- failed to unmarshal operation bytes: %w
- failed to marshal result: %w
- failed to decode Google tokeninfo response: %w
- INVALID_REQUEST
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/259cebf020c9e81e.
Report an issue: GitHub.