wavetermdev/waveterm · warning

Invalid request body: %v

Error message

Invalid request body: %v

What it means

The handler failed to JSON-decode the POST request body into PostMessageRequest and returns 400 with the decode error embedded. Causes are malformed JSON, wrong Content-Type handling, empty body, or body fields of the wrong type (e.g. arrays where objects are expected).

Source

Thrown at pkg/aiusechat/usechat.go:645

	BuilderId    string            `json:"builderid,omitempty"`
	BuilderAppId string            `json:"builderappid,omitempty"`
	ChatID       string            `json:"chatid"`
	Msg          uctypes.AIMessage `json:"msg"`
	WidgetAccess bool              `json:"widgetaccess,omitempty"`
	AIMode       string            `json:"aimode"`
}

func WaveAIPostMessageHandler(w http.ResponseWriter, r *http.Request) {
	// Only allow POST method
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// Parse request body
	var req PostMessageRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, fmt.Sprintf("Invalid request body: %v", err), http.StatusBadRequest)
		return
	}

	// Validate chatid is present and is a UUID
	if req.ChatID == "" {
		http.Error(w, "chatid is required in request body", http.StatusBadRequest)
		return
	}
	if _, err := uuid.Parse(req.ChatID); err != nil {
		http.Error(w, "chatid must be a valid UUID", http.StatusBadRequest)
		return
	}

	// Get RTInfo from TabId or BuilderId
	var rtInfo *waveobj.ObjRTInfo
	if req.TabId != "" {
		oref := waveobj.MakeORef(waveobj.OType_Tab, req.TabId)
		rtInfo = wstore.GetRTInfo(oref)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Send valid JSON with Content-Type: application/json and an object matching PostMessageRequest: {"chatid": "...", "message": "..."}.
  2. Inspect the %v detail in the 400 response — it names the exact JSON decode problem (unexpected end of JSON input, cannot unmarshal number into string, etc.).
  3. Check for proxies/middleware mangling the body (HTML error pages, chunked encoding issues) and ensure the raw body reaches the handler.

Example fix

// before
curl -X POST /api/aiusechat/message # empty body -> 400
// after
curl -X POST /api/aiusechat/message \
  -H 'Content-Type: application/json' \
  -d '{"chatid":"<uuid>","message":"hello"}'
Defensive patterns

Strategy: validation

Validate before calling

const body = { chatid: chatId, message: text, aimode: mode };
if (typeof chatid !== 'string' || chatid.length === 0) throw new Error('chatid required');
JSON.stringify(body); // throws early on non-serializable values

Type guard

function isPostMessageRequest(b) {
    return typeof b === 'object' && b !== null &&
        typeof b.chatid === 'string' && b.chatid.length > 0 &&
        typeof b.message === 'string';
}

Try / catch

const res = await fetch(url, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(payload) });
if (res.status === 400) {
    const text = await res.text();
    throw new Error(`request rejected: ${text}`); // includes JSON decode detail
}

Prevention

When it happens

Trigger: POSTing to the WaveAIPostMessageHandler route with a body that is not valid JSON (trailing commas, HTML error page from a proxy, empty payload), or with fields whose JSON types don't match PostMessageRequest (chatid/message must be strings, not numbers/objects).

Common situations: Forgetting to set Content-Type and sending form-encoded data; double-encoding the payload as a string; a load balancer returning an HTML 502 page that gets forwarded as the body; omitting the body entirely in a curl -X POST.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/9efb66ac6e816904. Report an issue: GitHub.