larksuite/cli · error
Device authorization failed: read body: %v
Error message
Device authorization failed: read body: %v
What it means
RequestDeviceAuthorization wraps an io.ReadAll failure while draining the device-authorization endpoint's HTTP response body. The HTTP request itself completed, but the response bytes could not be read (connection reset mid-body, timeout, truncated response). The %v verb embeds the underlying reader error without %w wrapping, so errors.Is/As cannot unwrap the cause.
Source
Thrown at internal/auth/device_flow.go:102
form.Set("scope", scope)
req, err := http.NewRequest("POST", endpoints.DeviceAuthorization, strings.NewReader(form.Encode()))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Authorization", "Basic "+basicAuth)
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
logHTTPResponse(resp)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Device authorization failed: read body: %v", err)
}
var data map[string]interface{}
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("Device authorization failed: HTTP %d – response not JSON", resp.StatusCode)
}
_, hasError := data["error"]
if resp.StatusCode >= 400 || hasError {
msg := getStr(data, "error_description")
if msg == "" {
msg = getStr(data, "error")
}
if msg == "" {
msg = "Unknown error"
}
return nil, fmt.Errorf("Device authorization failed: %s", msg)
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Retry RequestDeviceAuthorization — this is a transient transport-level read failure, not an auth rejection.
- Check network path to open.feishu.cn (proxy/VPN/firewall) and retry from a stable connection.
- If it recurs, capture the embedded error text after 'read body:' to identify the transport cause (reset, timeout, unexpected EOF).
- Consider replacing %v with %w when editing the code so callers can unwrap the cause.
Example fix
// before
return nil, fmt.Errorf("Device authorization failed: read body: %v", err)
// after
return nil, fmt.Errorf("Device authorization failed: read body: %w", err) Defensive patterns
Strategy: retry
Try / catch
// retry up to 3 times on transient body-read failure
for i := 0; i < 3; i++ {
resp, err := auth.RequestDeviceAuthorization(ctx, clientID, scopes)
if err == nil { break }
if strings.Contains(err.Error(), "read body:") && i < 2 { time.Sleep(backoff); continue }
return err
} Prevention
- Run the device flow on a stable network; avoid flaky VPN/proxy paths.
- Use a context with a generous timeout so partial reads fail fast and retry cleanly.
- When touching the code, wrap with %w so callers can errors.Is on transport errors.
- Log the underlying cause text for support diagnostics.
When it happens
Trigger: RequestDeviceAuthorization receives a 2xx/other response whose body read via io.ReadAll fails — server closes the connection mid-response, proxy truncates the transfer, or a network interruption occurs while streaming the body.
Common situations: Flaky corporate proxies or VPNs dropping keep-alive connections mid-body; Lark gateway timeouts on slow links; running the device flow behind an intercepting firewall that cuts large responses.
Related errors
- app registration failed: HTTP %d – response not JSON
- failed to read response body in security transport: %w
- index request failed: %s
- fetch bot info: %w
- annotated_csv did not parse into the rows the server reporte
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/8399d7f6c04579fa.
Report an issue: GitHub.