sipeed/picoclaw · error
reading device code response: %w
Error message
reading device code response: %w
What it means
io.ReadAll(resp.Body) failed while streaming the device-code response body (oauth.go:268). The POST got headers back, but the body read broke — connection reset mid-body, or the default http.Client's response-header timeout variant cutting a slow trickle. The status code is never inspected on this path.
Source
Thrown at pkg/auth/oauth.go:268
// Returns the info needed for the user to authenticate in a browser.
func RequestDeviceCode(cfg OAuthProviderConfig) (*DeviceCodeInfo, error) {
reqBody, _ := json.Marshal(map[string]string{
"client_id": cfg.ClientID,
})
resp, err := http.Post(
cfg.Issuer+"/api/accounts/deviceauth/usercode",
"application/json",
strings.NewReader(string(reqBody)),
)
if err != nil {
return nil, fmt.Errorf("requesting device code: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("reading device code response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("device code request failed: %s", string(body))
}
deviceResp, err := parseDeviceCodeResponse(body)
if err != nil {
return nil, fmt.Errorf("parsing device code response: %w", err)
}
if deviceResp.Interval < 1 {
deviceResp.Interval = 5
}
return &DeviceCodeInfo{
DeviceAuthID: deviceResp.DeviceAuthID,
UserCode: deviceResp.UserCode,
VerifyURL: cfg.Issuer + "/codex/device",View on GitHub (pinned to 49183d7e8d)
Solutions
- Retry RequestDeviceCode once or twice with a short backoff — transient body breaks dominate
- curl the same endpoint to confirm the body transfers cleanly outside the app
- Bypass or reconfigure intercepting proxies for the issuer host
- If persistent, capture with the wrapped error's errno/context and report upstream
Example fix
// before: one-shot device code request
info, err := auth.RequestDeviceCode(cfg)
// after: bounded retry on transport failure
var info *auth.DeviceCodeInfo
err := retryN(3, time.Second, func() error {
i, e := auth.RequestDeviceCode(cfg)
if i != nil { info = i }
return e
}) Defensive patterns
Strategy: retry
Try / catch
err := retryN(3, 500*time.Millisecond, func() error {
info, e := auth.RequestDeviceCode(cfg)
if e != nil && strings.Contains(e.Error(), "reading device code response") {
return e // mid-body truncation: retry
}
if info != nil { deviceInfo = info }
return retryStop{e}
}) Prevention
- Retry body-read failures of the device-code endpoint a bounded number of times
- Confirm clean transfers with curl when retries keep failing
- Avoid intercepting proxies on the issuer host
When it happens
Trigger: Server accepts the request then drops the connection during the body; an intermediary proxy flushing headers but truncating the body; flaky mobile/Wi-Fi links; server closing keep-alive prematurely.
Common situations: Unstable networks; aggressive proxy body limits; provider-side connection pool recycling mid-response.
Related errors
- reading usage response: %w
- requesting device code: %w
- Failed to load config
- Failed to fetch config
- API error %d: %s
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/bdeab8e09a1ad937.
Report an issue: GitHub.