vxcontrol/pentagi · error · Fatal

failed to marshal request body: %w

Error message

failed to marshal request body: %w

What it means

The Sploitus searcher wraps json.Marshal of the sploitusRequest struct; if marshaling fails the searcher returns a Fatal typed error that will not be retried. In practice a struct of plain fields cannot fail marshaling unless an unsupported type (e.g. channel, func, or a MarshalJSON method returning an error) is added to the request payload.

Source

Thrown at backend/pkg/tools/searchers/sploitus.go:120

		return "", err
	}

	return result, nil
}

// search calls the Sploitus API and returns a formatted markdown result string
func (s *sploitus) search(ctx context.Context, query, exploitType, sort string, limit int) (string, error) {
	reqBody := sploitusRequest{
		Query:  query,
		Type:   exploitType,
		Sort:   sort,
		Title:  false, // search only for titles
		Offset: 0,
	}

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

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

	client.Timeout = sploitusRequestTimeout

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, sploitusAPIURL, bytes.NewReader(bodyBytes))
	if err != nil {
		return "", Fatal(fmt.Errorf("failed to create request: %w", err))
	}

	// Build referer with query to mimic browser behavior
	referer := fmt.Sprintf("https://sploitus.com/?query=%s", url.QueryEscape(query))

	// Mimic Chrome browser headers to bypass Cloudflare protection

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped error to find the unsupported field type in sploitusRequest
  2. Remove or convert the offending field to a JSON-encodable type (string, []string, int, bool)
  3. Log the query/limit inputs passed from web_search.go to check no exotic value flows into the struct

Example fix

// before
reqBody := sploitusRequest{Query: query, Callback: fn} // fn is func: not encodable
// after
reqBody := sploitusRequest{Query: query, Offset: 0}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := json.Marshal(reqBody); err != nil {
    log.Fatalf("request payload not encodable: %v", err)
}

Type guard

func isJSONEncodable(v any) bool { var b bytes.Buffer; enc := json.NewEncoder(&b); return enc.Encode(v) == nil }

Try / catch

if _, err := json.Marshal(reqBody); err != nil {
    return "", Fatal(fmt.Errorf("failed to marshal request body: %w", err))
}

Prevention

When it happens

Trigger: Handle() on the Sploitus searcher builds reqBody and calls json.Marshal(reqBody); the error occurs when the request struct contains a value json cannot encode (unsupported type or a failing MarshalJSON implementation).

Common situations: A developer adds a field of type func, chan, sync.Mutex, or a custom type with a broken MarshalJSON method to sploitusRequest; it is almost never seen with the current struct of strings/ints/bools.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/9a3851971c3bbe0c. Report an issue: GitHub.