sipeed/picoclaw · error
failed to read request body
Error message
failed to read request body
What it means
Returned by POST /api/oauth/login (handleOAuthLogin) when io.ReadAll of the request body fails before parsing. The read is capped at 1 MiB; failure is transport-level (connection aborted mid-body, truncated chunked encoding), not payload content — bad JSON would produce 'invalid JSON: %v' instead.
Source
Thrown at web/backend/api/oauth.go:176
item.Status = "needs_refresh"
default:
item.Status = "connected"
}
}
providersResp = append(providersResp, item)
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"providers": providersResp,
})
}
func (h *Handler) handleOAuthLogin(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))
if err != nil {
http.Error(w, "failed to read request body", http.StatusBadRequest)
return
}
defer r.Body.Close()
var req struct {
Provider string `json:"provider"`
Method string `json:"method"`
Token string `json:"token"`
}
if err = json.Unmarshal(body, &req); err != nil {
http.Error(w, fmt.Sprintf("invalid JSON: %v", err), http.StatusBadRequest)
return
}
provider, err := normalizeOAuthProvider(req.Provider)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
returnView on GitHub (pinned to 49183d7e8d)
Solutions
- Retry the login POST — transient aborts dominate
- Prevent double-submit/abort races in the UI (disable the button while in flight)
- Check the reverse proxy's request-body timeout if it recurs
Defensive patterns
Strategy: validation
Validate before calling
function loginBody(provider: string, method: string, token?: string): string {
if (!provider || !method) throw new Error('provider and method are required');
return JSON.stringify({ provider, method, ...(token ? { token } : {}) });
} Try / catch
try {
const res = await fetch('/api/oauth/login', {...});
if (res.status === 400 && (await res.text()).includes('read request body')) {
/* aborted transfer — retry once with the same payload */
}
} catch (e) { /* network */ } Prevention
- Disable the login button while a login POST is in flight to avoid abort/double-submit
- Don't unmount the login form mid-request (guard route changes)
- Keep the login payload tiny — three string fields
When it happens
Trigger: Login POST aborted by the client after headers were sent; proxy cutting the body; Content-Length mismatch on a hand-rolled HTTP client.
Common situations: Login dialog unmounted mid-submit (SPA route change); aggressive proxy timeouts; curl interrupted mid-request; browser offline the moment login is clicked.
Related errors
- requesting device code: %w
- Failed to read request body
- Failed to load config
- Failed to fetch config
- error fetching models: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/aa948e299761c0ff.
Report an issue: GitHub.