googleapis/mcp-toolbox · error

failed to marshal request: %w

Error message

failed to marshal request: %w

What it means

FetchQueryStats marshals the FetchQueryStatsRequest to JSON before POSTing it to the queryStats:fetch REST endpoint. If json.Marshal fails, this wrapped error is returned. In practice this is rare because the request struct contains only JSON-serializable fields.

Source

Thrown at internal/sources/databaseinsights/databaseinsights.go:368

// DatabaseIndexRecommendation represents recommendations for a specific database.
type DatabaseIndexRecommendation struct {
	Database             string                      `json:"database"`
	IndexRecommendations []IndexRecommendation       `json:"indexRecommendations"`
	QueryImprovements    map[string]QueryImprovement `json:"queryImprovements"`
}

// BatchQueryIndexRecommendationsResponse contains index recommendations.
type BatchQueryIndexRecommendationsResponse struct {
	DatabaseIndexRecommendations []DatabaseIndexRecommendation `json:"databaseIndexRecommendations"`
}

// FetchQueryStats executes the FetchQueryStats REST API method.
func (s *Source) FetchQueryStats(ctx context.Context, req *FetchQueryStatsRequest) (*FetchQueryStatsResponse, error) {
	url := fmt.Sprintf("%s/v1beta/%s/queryStats:fetch", s.getEndpointForParent(req.Parent), req.Parent)

	bodyBytes, err := json.Marshal(req)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	httpReq, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(bodyBytes))
	if err != nil {
		return nil, fmt.Errorf("failed to create http request: %w", err)
	}
	httpReq.Header.Set("Content-Type", "application/json")

	resp, err := s.httpClient.Do(httpReq)
	if err != nil {
		return nil, fmt.Errorf("failed to execute request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		respBody, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("request failed with status %s: %s", resp.Status, string(respBody))
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Inspect the wrapped error to identify which field failed to marshal
  2. Audit FetchQueryStatsRequest fields for unsupported types (chan, func, complex)
  3. Validate the request payload constructed by the calling tool before invoking FetchQueryStats

Example fix

// before
req.Filter = someUnsupportedValue // e.g. a chan or func field
resp, err := s.FetchQueryStats(ctx, req)
// after
req.Filter = "valid-string-filter"
resp, err := s.FetchQueryStats(ctx, req)
Defensive patterns

Strategy: try-catch

Validate before calling

if b, err := json.Marshal(req); err != nil || len(b) == 0 {
  return fmt.Errorf("invalid FetchQueryStatsRequest: %w", err)
}

Try / catch

resp, err := src.FetchQueryStats(ctx, req)
if err != nil {
  if strings.Contains(err.Error(), "failed to marshal request") {
    // log req fields, fix serialization before retrying
  }
  return err
}

Prevention

When it happens

Trigger: json.Marshal(req) returns an error — typically only if the request struct (or a field within it) contains an unsupported type such as a channel, func, or complex number.

Common situations: A code change introducing an unsupported field type into FetchQueryStatsRequest; a custom JSONMarshaler on a field returning an error; corrupted in-memory data passed in by a tool.

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/5645df6f4c511024. Report an issue: GitHub.