sipeed/picoclaw · error
unexpected status %s: %s
Error message
unexpected status %s: %s
What it means
The WeCom HTTP GET returned a non-200 status with a readable body: the error is 'unexpected status <status>: <first 8KB of body>'. This is the primary non-OK diagnostic — e.g. '502 Bad Gateway: <html>...' from a relay behind a load balancer, or a 404 when the endpoint path moved. Because doWeComJSONGet is shared, this surfaces wrapped inside errors 124 and 131.
Source
Thrown at cmd/picoclaw/internal/auth/wecom.go:407
func doWeComJSONGet(ctx context.Context, client *http.Client, targetURL string, out any) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil)
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, readErr := io.ReadAll(io.LimitReader(resp.Body, 8192))
if readErr != nil {
return fmt.Errorf("unexpected status %s", resp.Status)
}
return fmt.Errorf("unexpected status %s: %s", resp.Status, strings.TrimSpace(string(body)))
}
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
return fmt.Errorf("decode JSON response: %w", err)
}
return nil
}
func wecomPlatformCode() int {
switch runtime.GOOS {
case "darwin":
return 1
case "windows":
return 2
case "linux":
return 3
default:View on GitHub (pinned to 49183d7e8d)
Solutions
- Read the embedded status and body: 5xx = relay trouble, retry later; 403/404 = endpoint/proxy issue, update picoclaw or fix proxy
- curl -v the same URL to confirm it is reproducible outside picoclaw
- Retry after a short backoff for 502/503/504
- Update picoclaw to the latest release so endpoint paths match the relay
Defensive patterns
Strategy: retry
Type guard
func isRetryableStatus(err error) bool {
msg := err.Error()
return strings.Contains(msg, "unexpected status 502") ||
strings.Contains(msg, "unexpected status 503") ||
strings.Contains(msg, "unexpected status 504") ||
strings.Contains(msg, "unexpected status 429")
} Try / catch
err := doWeComJSONGet(ctx, client, target, out)
if isRetryableStatus(err) {
time.Sleep(backoff)
err = doWeComJSONGet(ctx, client, target, out)
}
if err != nil {
return err
} Prevention
- Retry 5xx/429 with exponential backoff; never retry 4xx except 429
- Keep picoclaw updated so endpoint paths match the relay
When it happens
Trigger: Relay or its CDN returning 502/503/504; 404 after an endpoint path change between picoclaw and relay versions; 429 from rate limiting; a proxy returning an HTML block page.
Common situations: Relay outage or rolling deploy during login; old picoclaw against a moved endpoint; corporate proxy blocking the relay with a 403 page.
Related errors
- failed to get WeCom QR code: %w
- unexpected status %s
- create request: %w
- API error %d: %s
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/4715f56421d0391c.
Report an issue: GitHub.