vxcontrol/pentagi · error · FatalError

failed to marshal request body: %v

Error message

failed to marshal request body: %v

What it means

Before sending the search request, firecrawl marshals its firecrawlRequest payload with encoding/json; failure is wrapped in a FatalError. With the current struct this is practically impossible, so it guards against future type mismatches (e.g. unsupported field types).

Source

Thrown at backend/pkg/tools/searchers/firecrawl.go:153

	client, err := system.GetHTTPClient(f.cfg)
	if err != nil {
		return "", Fatal(fmt.Errorf("failed to create http client: %w", err))
	}

	// sources is intentionally omitted: /v2/search defaults to ["web"], which is
	// all this tool consumes, and it avoids the string-vs-object shape ambiguity
	// that field carries across the API/SDK layers.
	reqPayload := firecrawlRequest{
		Query: query,
		Limit: maxResults,
		ScrapeOptions: &firecrawlScrapeOptions{
			Formats:         []string{"markdown"},
			OnlyMainContent: true,
		},
	}
	reqBody, err := json.Marshal(reqPayload)
	if err != nil {
		return "", Fatal(fmt.Errorf("failed to marshal request body: %v", err))
	}

	req, err := http.NewRequest(http.MethodPost, f.searchURL(), bytes.NewBuffer(reqBody))
	if err != nil {
		return "", Fatal(fmt.Errorf("failed to build request: %v", err))
	}

	req = req.WithContext(ctx)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+f.apiKey())

	resp, err := client.Do(req)
	if err != nil {
		return "", Retryable(fmt.Errorf("failed to do request: %v", err), 0)
	}
	defer resp.Body.Close()

	return f.parseHTTPResponse(ctx, query, resp)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped %v cause to find which field fails to marshal.
  2. Audit firecrawlRequest for chan/func/cyclic fields after recent changes.
  3. Fix or remove the offending field, or add a MarshalJSON for it.

Example fix

// before
Timeout int // custom marshaller returning error
// after
Timeout *int  // plain serializable type, or fix MarshalJSON
Defensive patterns

Strategy: validation

Validate before calling

if _, err := json.Marshal(reqPayload); err != nil {
  return fmt.Errorf("payload not serializable: %v", err)
}

Prevention

When it happens

Trigger: json.Marshal(reqPayload) errors — only possible if the payload struct gains unmarshalable fields (chan/func) or a custom MarshalJSON returns an error.

Common situations: After code changes introducing non-serializable fields into firecrawlRequest, or a custom marshaller bug.

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 vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/0c09f14622c98f8f. Report an issue: GitHub.