sipeed/picoclaw · error

unexpected status %s

Error message

unexpected status %s

What it means

The WeCom HTTP GET returned a non-200 status AND reading (up to 8KB of) the response body also failed. The double failure means the connection broke mid-response (e.g. reset after headers), so the error carries only the status line like 'unexpected status 502 Bad Gateway' without the body detail that error 137 includes.

Source

Thrown at cmd/picoclaw/internal/auth/wecom.go:405

	return u.String(), nil
}

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":

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Retry the login — a reset mid-body is usually transient
  2. If persistent, curl -v the endpoint to see whether the status+reset reproduces
  3. Check for middleboxes/proxies that reset long-lived or suspicious responses
  4. Update picoclaw if the relay changed behavior (new default endpoints)
Defensive patterns

Strategy: retry

Type guard

func isConnectionReset(err error) bool {
	return errors.Is(err, syscall.ECONNRESET) || strings.Contains(err.Error(), "connection reset")
}

Try / catch

if resp.StatusCode != http.StatusOK {
	body, readErr := io.ReadAll(io.LimitReader(resp.Body, 8192))
	if readErr != nil {
		// transient reset: retry the request once before failing
	}
	return fmt.Errorf("unexpected status %s: %s", resp.Status, strings.TrimSpace(string(body)))
}

Prevention

When it happens

Trigger: Server sends a 5xx status then resets the connection before the body; proxy tears down the stream; mobile/flaky network dropping between headers and body; very large headers plus tiny timeouts.

Common situations: Flaky mobile hotspot during login; aggressive firewall RST; relay crash mid-response.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/5541e1bcedd2b7ab. Report an issue: GitHub.