{"record":{"id":"80e4855b372cfb2c","repo":"langfuse/langfuse","slug":"invalid-json-body","errorCode":null,"errorMessage":"Invalid JSON body","messagePattern":"Invalid JSON body","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"web/src/pages/api/public/scim/Users/[id].ts","lineNumber":535,"sourceCode":"\n// PATCH - Update user details (Use only for deprovisioning for now)\n// Payload is a string like: \"{\\\"schemas\\\":[\\\"urn:ietf:params:scim:api:messages:2.0:PatchOp\\\"],\\\"Operations\\\":[{\\\"op\\\":\\\"replace\\\",\\\"value\\\":{\\\"active\\\":false}}]}\"\nasync function handlePatch(\n  req: NextApiRequest,\n  res: NextApiResponse,\n  user: User,\n  orgId: string,\n  apiKeyId: string,\n) {\n  let body = req.body;\n\n  // Check if body is a string and parse it\n  if (typeof body === \"string\") {\n    try {\n      body = JSON.parse(body);\n    } catch (error) {\n      logger.warn(\"[SCIM] Failed to parse JSON body\", error);\n      return res.status(400).json({\n        schemas: [\"urn:ietf:params:scim:api:messages:2.0:Error\"],\n        detail: \"Invalid JSON body\",\n        status: 400,\n      });\n    }\n  }\n\n  // Validate the request body\n  if (\n    !body.schemas ||\n    !Array.isArray(body.schemas) ||\n    !body.schemas.includes(\"urn:ietf:params:scim:api:messages:2.0:PatchOp\")\n  ) {\n    logger.warn(\n      \"[SCIM] Invalid request body. Must include 'schemas' with 'urn:ietf:params:scim:api:messages:2.0:PatchOp'.\",\n      body,\n    );\n    return res.status(400).json({","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/langfuse/langfuse/blob/59d92c7cf365150d10b753b5a0d1708902a2ed60/web/src/pages/api/public/scim/Users/[id].ts#L517-L553","documentation":"Returned when the PATCH body arrives as a string that fails JSON.parse. Next.js usually parses JSON bodies automatically, so this fires when the body is malformed JSON or the client sends a string content type.","triggerScenarios":"PATCH /api/public/scim/Users/{id} with a syntactically invalid JSON body (trailing commas, truncated payload, wrong quotes).","commonSituations":"Hand-crafted curl requests with broken quoting; proxies or IdP connectors mangling the payload; sending form-encoded data where JSON is expected.","solutions":["Validate the request body with a JSON linter before sending","Ensure Content-Type: application/json is set and the payload is a single valid JSON object","Capture the exact request (e.g. requestbin) to see what the IdP actually transmits"],"exampleFix":"// before (invalid)\ncurl -X PATCH .../Users/123 -d \"{active: true}\"  // unquoted key\n// after\ncurl -X PATCH .../Users/123 -H 'Content-Type: application/json' -d '{\"schemas\":[\"urn:ietf:params:scim:api:messages:2.0:PatchOp\"],\"Operations\":[{\"op\":\"replace\",\"value\":{\"active\":true}}]}'\n","handlingStrategy":"validation","validationCode":"try { JSON.parse(rawBody); } catch { throw new Error('Body is not valid JSON — fix before sending'); }\n","typeGuard":"const isParsableJson = (s: string) => { try { JSON.parse(s); return true; } catch { return false; } };","tryCatchPattern":"Catch the 400 and surface the raw payload to whoever generated it; do not retry unchanged.","preventionTips":["Always send Content-Type: application/json","Lint SCIM payloads in integration tests"],"tags":["scim","json","http-400","request-body"],"backgroundTag":"invalid-json-body","analyzedSha":"59d92c7cf365150d10b753b5a0d1708902a2ed60","analyzedAt":"2026-08-27T22:22:00.402Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}