{"record":{"id":"1a45582d413db323","repo":"risingwavelabs/risingwave","slug":"failed-to-decode-webhook-json-payload","errorCode":null,"errorMessage":"failed to decode webhook JSON payload","messagePattern":"failed to decode webhook JSON payload","errorType":"http","errorClass":null,"httpStatus":422,"severity":"warning","filePath":"src/frontend/src/webhook/payload.rs","lineNumber":55,"sourceCode":"pub(crate) fn build_json_access_builder(headers: &HeaderMap) -> Result<JsonAccessBuilder> {\n    JsonAccessBuilder::new(json_properties_from_headers(headers)?).map_err(|e| {\n        err(\n            anyhow!(e).context(\"failed to build webhook JSON decoder\"),\n            StatusCode::INTERNAL_SERVER_ERROR,\n        )\n    })\n}\n\npub(crate) fn owned_row_from_payload_row(\n    access_builder: &mut JsonAccessBuilder,\n    columns: &[WebhookTableColumnDesc],\n    payload_row: &[u8],\n) -> Result<OwnedRow> {\n    let access = access_builder\n        .generate_json_access(payload_row.to_vec())\n        .map_err(|e| {\n            err(\n                anyhow!(e).context(\"failed to decode webhook JSON payload\"),\n                StatusCode::UNPROCESSABLE_ENTITY,\n            )\n        })?;\n    let row = columns\n        .iter()\n        .map(\n            |column| match access.access(&[column.name.as_str()], &column.data_type) {\n                Ok(datum) => Ok(datum.to_owned_datum()),\n                Err(error) if column.is_pk => Err(error),\n                Err(_) => Ok(None),\n            },\n        )\n        .collect::<AccessResult<Vec<_>>>()\n        .map(OwnedRow::new);\n    row.map_err(|e| {\n        err(\n            anyhow!(e).context(\"failed to decode webhook JSON payload\"),\n            StatusCode::UNPROCESSABLE_ENTITY,","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/webhook/payload.rs#L37-L73","documentation":"The webhook JSON body could not be parsed into JSON access values (`generate_json_access` failed). The request payload is not valid JSON or does not match the decoder's expectations, so the service rejects it with HTTP 422 UNPROCESSABLE_ENTITY. This is a client-side payload problem, not a server fault.","triggerScenarios":"POST a body that is not valid JSON (trailing comma, truncated payload, HTML error page); binary or form-encoded body sent to a JSON webhook; payload exceeds decoder limits or contains a structure the accessor cannot traverse.","commonSituations":"Producer serializes with the wrong content type; a gateway truncates large bodies; payload is form-urlencoded or multipart instead of JSON; a failed upstream call returns an error page that gets forwarded to the webhook.","solutions":["Validate the body is well-formed JSON (e.g. JSON.parse in the producer) before sending.","Set `Content-Type: application/json` and send a UTF-8 JSON document.","Log/inspect the exact payload bytes that were rejected and compare with the table's expected schema.","Ensure no proxy/gateway is truncating or transforming the body.","For large payloads, check the JSON column handling headers and payload size limits."],"exampleFix":"// before\nsend(JSON.stringify({a: 1,})); // trailing comma -> invalid JSON\n// after\nconst body = JSON.stringify({a: 1});\nJSON.parse(body); // sanity check\nsend(body);","handlingStrategy":"validation","validationCode":"// validate payload before posting\nconst body = JSON.stringify(event);\nJSON.parse(body); // throws locally if invalid\nconst res = await fetch(url, { method: 'POST', headers: {'content-type':'application/json'}, body });","typeGuard":"function isJsonObject(x) { return x !== null && typeof x === 'object' && !Array.isArray(x); }\nif (!isJsonObject(event)) throw new Error('webhook payload must be a JSON object');","tryCatchPattern":"try {\n  const res = await fetch(url, { method: 'POST', headers: {'content-type':'application/json'}, body });\n  if (res.status === 422) throw new Error('payload rejected as invalid JSON: ' + (await res.text()));\n} catch (e) { log('webhook payload error', e); }","preventionTips":["Always serialize with JSON.stringify and content-type application/json","Dry-run payloads through a local JSON parser before shipping","Log rejected payloads for replay after fixing","Keep payloads within documented size limits"],"tags":["webhook","json","payload","validation"],"backgroundTag":"json-decode-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}