googleapis/mcp-toolbox · error

error decoding raw message: %w

Error message

error decoding raw message: %w

What it means

While iterating the JSON array with decoder.More(), each element is decoded into a json.RawMessage. If a decode step fails for a reason other than clean EOF (malformed JSON mid-stream, invalid UTF-8, truncated element), this wrapped error is returned.

Source

Thrown at internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go:312

	var messages []map[string]any
	decoder := json.NewDecoder(resp.Body)
	dataMsgIdx := -1

	// The response is a JSON array, so we read the opening bracket.
	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 {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Retry the request; mid-stream corruption is usually transient network/load-balancer behavior.
  2. Increase idle/read timeouts on proxies and load balancers in front of the toolbox to keep long streaming responses alive.
  3. Check proxy buffering settings (e.g. disable response buffering for streaming endpoints).
  4. Log the partial raw message around the failure to identify where truncation occurs.

Example fix

// before: nginx default proxy_read_timeout 60s kills long streams
// after
//   proxy_read_timeout 600s;
//   proxy_buffering off;
Defensive patterns

Strategy: retry

Try / catch

result, err := tool.Invoke(ctx, params)
if err != nil && strings.Contains(err.Error(), "error decoding raw message") {
    // mid-stream truncation: safe to retry, request had no side effects beyond read
    return retryWithBackoff(req, 3)
}

Prevention

When it happens

Trigger: Invoke on the tool when the streamed GDA response contains a corrupt or truncated JSON element inside the array — typically from a dropped connection mid-stream or a malformed element produced by the API/proxy.

Common situations: Unstable network dropping the connection mid-response; aggressive idle timeouts on load balancers killing long streams; proxy buffering limits truncating the body.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/8e1169dbb316a05e. Report an issue: GitHub.