risingwavelabs/risingwave · error
failed to parse request body
Error message
failed to parse request body
What it means
When the webhook body is not batched, generate_data_chunk parses the entire body as a single JSON value via Value::from_text. If parsing fails, the error is wrapped with context 'failed to parse request body' and returned with HTTP 422 (Unprocessable Entity). The webhook expects a valid JSON document per row.
Source
Thrown at src/frontend/src/webhook/mod.rs:191
if res.status == fast_insert_response::Status::Succeeded as i32 {
Ok(())
} else {
Err(err(
anyhow!("Fast insert failed: {}", res.error_message),
StatusCode::INTERNAL_SERVER_ERROR,
))
}
}
fn generate_data_chunk(is_batched: bool, body: &Bytes) -> Result<DataChunk> {
let mut builder = JsonbArrayBuilder::with_type(1, DataType::Jsonb);
if !is_batched {
// Use builder to obtain a single column & single row DataChunk
let json_value = Value::from_text(body).map_err(|e| {
err(
anyhow!(e).context("failed to parse request body"),
StatusCode::UNPROCESSABLE_ENTITY,
)
})?;
let jsonb_val = JsonbVal::from(json_value);
builder.append(Some(jsonb_val.as_scalar_ref()));
Ok(DataChunk::new(vec![builder.finish().into_ref()], 1))
} else {
let rows: Vec<_> = body
.split(|&b| b == b'\n')
.filter(|b| !b.is_empty())
.collect();
for row in &rows {
let json_value = Value::from_text(row).map_err(|e| {
err(
anyhow!(e).context("failed to parse request body"),View on GitHub (pinned to 6469eb736d)
Solutions
- Validate the body is a single well-formed JSON document (jq . body.json should succeed).
- Set Content-Type: application/json and send the raw JSON object as the body.
- If sending multiple records, use the batched endpoint format (array of objects) instead.
- Log the raw body server-side and re-test with curl --data-binary to rule out encoding issues.
Example fix
// before
curl -X POST -d 'key=value' .../webhook/table/orders
// after
curl -X POST -H 'Content-Type: application/json' -d '{"id":1,"item":"x"}' .../webhook/table/orders Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check
const body = await res.text();
JSON.parse(body); // throws locally before sending if invalid
if (!body.trim().startsWith('{')) throw new Error('webhook body must be a single JSON object'); Type guard
function isJsonObject(s: string): boolean {
try { const v = JSON.parse(s); return typeof v === 'object' && v !== null && !Array.isArray(v); }
catch { return false; }
} Try / catch
try {
await postWebhook(url, body);
} catch (e) {
if (e.status === 422 && e.message.includes('failed to parse request body')) {
logInvalidBody(rawBody); // inspect and fix producer
} else { throw e; }
} Prevention
- Always send Content-Type: application/json with a raw JSON object body.
- Validate the payload with a JSON parser before sending.
- Use the batched format for multiple records, not NDJSON to a single-row endpoint.
- Guard against proxies/gateways truncating or re-encoding bodies.
When it happens
Trigger: POSTing a non-batched webhook request whose body is not valid JSON: empty body, truncated JSON, HTML/text payloads, wrong Content-Type content, or JSON that fails jsonb parsing rules (e.g. duplicate handling, non-object roots where required).
Common situations: Senders posting form-encoded or plain-text data; proxies truncating large bodies; webhook producers emitting NDJSON (multiple JSON lines) to a single-object endpoint.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- schema from {url} not valid JSON
- error parsing with props json
- failed to build webhook JSON decoder
- failed to decode webhook JSON payload
- Field '{}' not found in secret
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/5ea6b3568bfeb254.
Report an issue: GitHub.