router-for-me/CLIProxyAPI · error

marshal request body

Error message

marshal request body: %w

What it means

Returned by AntigravityAuth.FetchProjectID when encoding the loadCodeAssist request body to JSON fails. The payload is a statically built map ({"metadata": {"ideType": "ANTIGRAVITY"}}) containing only string keys and string values, so json.Marshal cannot fail for any realistic input. The error exists only as a defensive guard against programming mistakes (e.g. someone later adding an unmarshalable type such as a channel or func to the map). If you see it, code was modified to put an unsupported type into loadReqBody.

Solutions

  1. Inspect antigravityLoadCodeAssistMetadata() and any local additions to loadReqBody for values of type chan, func, complex, or self-referencing structs
  2. Replace unmarshalable values with their string or plain-struct equivalents
  3. Run go test ./internal/auth/antigravity/ to confirm the round trip
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := auth.FetchProjectID(ctx, token); err != nil {
    var target *json.MarshalerError // not directly reachable; treat as programming bug
    if errors.As(err, &target) {
        log.Errorf("request payload bug: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling FetchProjectID after the request-body map was changed to contain a value json.Marshal cannot encode (chan, func, complex, cyclic pointer). With the shipped literal map this branch is effectively unreachable.

Common situations: Developers extending antigravityLoadCodeAssistMetadata() with non-string fields (timestamps as time.Time are fine, but func values or cyclic structs are not); essentially never seen in production.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/9616d47a2192d4a0. Report an issue: GitHub.

Appendix: source

Thrown at internal/auth/antigravity/auth.go:235

		return "", fmt.Errorf("antigravity userinfo: decode response: %w", errDecode)
	}
	email := strings.TrimSpace(info.Email)
	if email == "" {
		return "", fmt.Errorf("antigravity userinfo: response missing email")
	}
	return email, nil
}

// FetchProjectID retrieves the project ID for the authenticated user via loadCodeAssist
func (o *AntigravityAuth) FetchProjectID(ctx context.Context, accessToken string) (string, error) {
	userAgent := o.shortUserAgent()
	loadReqBody := map[string]any{
		"metadata": antigravityLoadCodeAssistMetadata(),
	}

	rawBody, errMarshal := json.Marshal(loadReqBody)
	if errMarshal != nil {
		return "", fmt.Errorf("marshal request body: %w", errMarshal)
	}

	endpointURL := fmt.Sprintf("%s/%s:loadCodeAssist", APIEndpoint, APIVersion)
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpointURL, strings.NewReader(string(rawBody)))
	if err != nil {
		return "", fmt.Errorf("create request: %w", err)
	}
	req.Header.Set("Authorization", "Bearer "+accessToken)
	req.Header.Set("Accept", "*/*")
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("User-Agent", userAgent)

	resp, errDo := o.httpClient.Do(req)
	if errDo != nil {
		return "", fmt.Errorf("execute request: %w", errDo)
	}
	defer func() {
		if errClose := resp.Body.Close(); errClose != nil {

View on GitHub (pinned to 78f0c4079e)