googleapis/mcp-toolbox · error
error unmarshaling raw message: %w
Error message
error unmarshaling raw message: %w
What it means
After a raw array element is decoded, getStream unmarshals it into map[string]any to inspect its message type. Failure here means the element was valid JSON but not a JSON object (e.g. a bare string, number, or array inside the outer array), which the code cannot interpret as a GDA message.
Source
Thrown at internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go:317
if _, err := decoder.Token(); err != nil {
if err == io.EOF {
return "", nil // Empty response is valid
}
return "", fmt.Errorf("error reading start of json array: %w", err)
}
for decoder.More() {
var rawMsg json.RawMessage
if err := decoder.Decode(&rawMsg); err != nil {
if err == io.EOF {
break
}
return "", fmt.Errorf("error decoding raw message: %w", err)
}
var msg map[string]any
if err := json.Unmarshal(rawMsg, &msg); err != nil {
return "", fmt.Errorf("error unmarshaling raw message: %w", err)
}
var processedMsg map[string]any
if dataResult := extractDataResult(msg); dataResult != nil {
// 1. If it's a data result, format it.
processedMsg = formatDataRetrieved(dataResult, maxRows)
if dataMsgIdx >= 0 {
// Replace previous data with a placeholder. Intermediate data results in a
// stream are redundant and consume unnecessary tokens.
messages[dataMsgIdx] = map[string]any{"Data Retrieved": "Intermediate result omitted"}
}
dataMsgIdx = len(messages)
} else if sm, ok := msg["systemMessage"].(map[string]any); ok {
// 2. If it's a system message, unwrap it.
processedMsg = sm
} else {
// 3. Otherwise (e.g. error), pass it through raw.
processedMsg = msgView on GitHub (pinned to 8cc6e09de2)
Solutions
- Update the toolbox to the latest version so message parsing matches the current GDA API contract.
- If using mocks/fixtures, make every array element a JSON object (e.g. {"systemMessage": {...}} or {"dataResult": {...}}).
- Log the offending raw message to confirm its shape and compare against the documented GDA chat response schema.
Example fix
// before: fixture element is a string
["ok"]
// after: element must be an object
[{"systemMessage": {"text": "ok"}}] Defensive patterns
Strategy: validation
Validate before calling
for _, el := range elements {
if el[0] != '{' {
return fmt.Errorf("array element is not a JSON object: %s", el)
}
} Type guard
func isJSONObject(raw json.RawMessage) bool {
var m map[string]any
return json.Unmarshal(raw, &m) == nil && m != nil
} Try / catch
result, err := tool.Invoke(ctx, params)
if err != nil && strings.Contains(err.Error(), "error unmarshaling raw message") {
return fmt.Errorf("unexpected GDA response element; upgrade toolbox or fix mock: %w", err)
} Prevention
- Keep the toolbox version current with the GDA API contract.
- Ensure test fixtures/mocks emit JSON objects only.
- Compare unexpected elements against the documented chat response schema.
When it happens
Trigger: Invoke on the tool when the GDA response array contains an element that is not a JSON object — only possible with an unexpected API contract change or a fake/mocked endpoint emitting non-object elements.
Common situations: Mock servers or integration fixtures with wrong element shapes; version drift where the API adds non-object sentinel elements; hand-crafted test payloads.
Related errors
- error reading start of json array: %w
- error parsing JSON: %v
- failed to marshal payload: %w
- error decoding raw message: %w
- error marshalling message: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/0c35672c1bcdf81a.
Report an issue: GitHub.