googleapis/mcp-toolbox · error

failed to marshal query body: %w

Error message

failed to marshal query body: %w

What it means

Thrown in RunSQL when json.Marshal fails to serialize the ES|QL request body ({query, params}). In practice the query string and params slice are always JSON-serializable, so this is a defensive wrapper around an almost-impossible failure mode.

Source

Thrown at internal/sources/elasticsearch/elasticsearch.go:179

	Type string `json:"type"`
}

type EsqlResult struct {
	Columns []EsqlColumn `json:"columns"`
	Values  [][]any      `json:"values"`
}

func (s *Source) RunSQL(ctx context.Context, format, query string, params []map[string]any) (any, error) {
	bodyStruct := struct {
		Query  string           `json:"query"`
		Params []map[string]any `json:"params,omitempty"`
	}{
		Query:  query,
		Params: params,
	}
	body, err := json.Marshal(bodyStruct)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal query body: %w", err)
	}

	res, err := esapi.EsqlQueryRequest{
		Body:       bytes.NewReader(body),
		Format:     format,
		FilterPath: []string{"columns", "values"},
		Instrument: s.ElasticsearchClient().InstrumentationEnabled(),
	}.Do(ctx, s.ElasticsearchClient())

	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.IsError() {
		// Try to extract error message from response
		var esErr json.RawMessage
		err = util.DecodeJSON(res.Body, &esErr)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Inspect any custom code that builds the `params` argument and remove non-serializable values (func, channel, cyclic maps)
  2. Ensure params is []map[string]any containing only JSON-compatible values
  3. If it persists, log the wrapped underlying error (%w) for the offending value
Defensive patterns

Strategy: validation

Validate before calling

// ensure params are JSON-serializable before calling RunSQL
if _, err := json.Marshal(params); err != nil {
    return fmt.Errorf("params not JSON-serializable: %w", err)
}

Prevention

When it happens

Trigger: Only if params contains values json.Marshal cannot handle — e.g. channel, func, or cyclic data structures injected programmatically rather than through normal tool invocation.

Common situations: Custom tool code passing non-JSON-serializable parameter maps directly to RunSQL; virtually never seen through standard YAML-configured tool invocation.

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 googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/59da7cb9eea1fb7d. Report an issue: GitHub.