googleapis/mcp-toolbox · error
failed to marshal payload: %w
Error message
failed to marshal payload: %w
What it means
getStream serializes the Conversational Analytics request payload (CAPayload) to JSON before POSTing it. If json.Marshal fails — e.g. the payload contains a value that cannot be marshaled such as a channel, func, or unsupported custom type — the function returns this wrapped error without making the HTTP call.
Source
Thrown at internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go:428
ResultNaturalLanguage string `json:"resultNaturalLanguage,omitempty"`
ResultCsvData string `json:"resultCsvData,omitempty"`
ResultReferenceData string `json:"resultReferenceData,omitempty"`
Error string `json:"error,omitempty"`
}
type AnalysisMessage struct {
Query AnalysisQuery `json:"query,omitempty"`
ProgressEvent AnalysisEvent `json:"progressEvent,omitempty"`
}
// ErrorResponse represents an error message from the API.
type ErrorMessage struct {
Text string `json:"text"`
}
func getStream(ctx context.Context, client *http.Client, url string, payload CAPayload, headers map[string]string) ([]map[string]any, error) {
payloadBytes, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("failed to marshal payload: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
if err != nil {
return nil, 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 nil, 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
- Inspect the wrapped %w error to find the unmarshalable field
- Ensure all CAPayload fields are JSON-safe (strings, slices, maps, numbers)
- Remove or convert custom types to primitives before building the payload
- Add a unit test marshaling your payload construction path
Example fix
// before
payload.Data = make(chan int)
// after
payload.Data = map[string]any{"key": "value"} 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
resp, err := getStream(ctx, client, url, payload, headers)
if err != nil {
var mk *json.MarshalTypeError
if errors.As(err, &mk) {
log.Printf("bad field %s at offset %d", mk.Field, mk.Offset)
}
return err
} Prevention
- Keep CAPayload fields restricted to JSON-native types
- Add round-trip marshal tests for payload builders
When it happens
Trigger: Constructing a CAPayload whose nested fields (userQueryWithcontext, exploreReferences, options, etc.) include non-JSON-marshalable Go values; programmatic Go callers building the payload manually.
Common situations: Custom Go code extending the payload with unsupported field types; cyclic data structures; fields populated from goroutine-unsafe shared state.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- error marshaling dynamic_fields: %w
- failed to marshal result: %w
- operation finished with error but could not marshal error ob
- failed to unmarshal operation bytes: %w
- failed to unmarshal json: %w, body: %s
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/6c7e480220a94283.
Report an issue: GitHub.