wavetermdev/waveterm · error
failed to read request body: %v
Error message
failed to read request body: %v
What it means
handleRender reads the entire request body with io.ReadAll; a read failure returns HTTP 400 'failed to read request body: <err>' (tsunami/engine/serverhandlers.go:118). The client's request was malformed or the connection broke mid-upload.
Source
Thrown at tsunami/engine/serverhandlers.go:118
func (h *httpHandlers) handleRender(w http.ResponseWriter, r *http.Request) {
defer func() {
panicErr := util.PanicHandler("handleRender", recover())
if panicErr != nil {
http.Error(w, fmt.Sprintf("internal server error: %v", panicErr), http.StatusInternalServerError)
}
}()
setNoCacheHeaders(w)
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, fmt.Sprintf("failed to read request body: %v", err), http.StatusBadRequest)
return
}
var feUpdate rpctypes.VDomFrontendUpdate
if err := json.Unmarshal(body, &feUpdate); err != nil {
http.Error(w, fmt.Sprintf("failed to parse JSON: %v", err), http.StatusBadRequest)
return
}
if feUpdate.ForceTakeover {
h.Client.clientTakeover(feUpdate.ClientId)
}
if err := h.Client.checkClientId(feUpdate.ClientId); err != nil {
http.Error(w, fmt.Sprintf("client id error: %v", err), http.StatusBadRequest)
return
}
View on GitHub (pinned to a4447c1563)
Solutions
- Inspect the wrapped error (unexpected EOF, body too large) to pick the right fix.
- Retry the POST; transient disconnects resolve on resend.
- Reduce payload size or raise body-size limits on the server/proxy.
- Ensure the client fully writes the body before reading the response and does not cancel the request early.
Example fix
// before: aborting mid-send
c.abort() // while fetch body still uploading
// after: await the request completion
await fetch(renderUrl, {method: "POST", body: JSON.stringify(feUpdate), signal: controller.signal}) Defensive patterns
Strategy: retry
Validate before calling
const payload = JSON.stringify(feUpdate);
if (payload.length > MAX_BODY_BYTES) throw new Error("render payload too large"); Try / catch
const resp = await fetch(renderUrl, {method: "POST", body: payload});
if (resp.status === 400 && (await resp.text()).includes("failed to read request body")) {
return retryWithBackoff(() => fetch(renderUrl, {method: "POST", body: payload}));
} Prevention
- Keep render payloads small; batch or chunk large updates.
- Do not cancel fetch requests while the body is still uploading.
- Match proxy/client/server timeouts for large POSTs.
When it happens
Trigger: The HTTP body is truncated by a disconnect, a body-size limit trips, or the client aborts the POST before finishing the upload.
Common situations: Large render payloads over unstable connections, proxy timeouts cutting uploads short, test harnesses sending a closed/empty body reader.
Related errors
- Error reading request body: %v
- wcloud endpoint not set
- wcloud ping endpoint not set
- reading input: %w
- failed to copy data: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/6c788c0693794711.
Report an issue: GitHub.