router-for-me/CLIProxyAPI · error

decode response: %w

Error message

decode response: %w

What it means

Returned by AntigravityAuth.FetchProjectID when the loadCodeAssist endpoint returns 2xx but the body is not valid JSON. The code unconditionally json.Unmarshals the body into map[string]any, so any HTML error page, empty body, or plain-text response from an interceptor triggers this. With the real Google endpoint a 2xx always carries JSON, so this almost always means something between the client and Google (captive portal, authenticating proxy) rewrote the response.

Source

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

	}
	defer func() {
		if errClose := resp.Body.Close(); errClose != nil {
			log.Errorf("antigravity loadCodeAssist: close body error: %v", errClose)
		}
	}()

	bodyBytes, errRead := io.ReadAll(resp.Body)
	if errRead != nil {
		return "", fmt.Errorf("read response: %w", errRead)
	}

	if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
		return "", fmt.Errorf("request failed with status %d: %s", resp.StatusCode, strings.TrimSpace(string(bodyBytes)))
	}

	var loadResp map[string]any
	if errDecode := json.Unmarshal(bodyBytes, &loadResp); errDecode != nil {
		return "", fmt.Errorf("decode response: %w", errDecode)
	}

	projectID := extractCloudaicompanionProject(loadResp)

	if projectID == "" {
		projectID, err = o.OnboardUser(ctx, accessToken, defaultAntigravityTierID(loadResp))
		if err != nil {
			return "", err
		}
		if projectID == "" {
			return "", fmt.Errorf("project id not found in loadCodeAssist or onboardUser response")
		}
		return projectID, nil
	}

	return projectID, nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Log or inspect bodyBytes (already captured in the caller) to see what non-JSON payload came back — an HTML title usually names the interceptor
  2. Bypass or authenticate with the captive portal / corporate proxy, then retry
  3. If testing, make the stub return Content-Type: application/json with a valid loadCodeAssist-shaped object
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := auth.FetchProjectID(ctx, token); err != nil {
    var syn *json.SyntaxError
    if errors.As(err, &syn) {
        log.Errorf("non-JSON 2xx from loadCodeAssist — likely captive portal/proxy rewrite: %v", err)
    }
}

Prevention

When it happens

Trigger: A captive portal or transparent proxy answering 200 with an HTML login page; a mock/stub server in tests returning 200 with an empty or non-JSON body; a misconfigured SSL-offloading appliance injecting plain text.

Common situations: Running the proxy on guest Wi-Fi with a captive portal; corporate TLS-inspecting middleboxes; local development against a fake cloudcode-pa endpoint that forgot to set a JSON body.

Related errors


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