{"record":{"id":"7160975b35fe2d13","repo":"calcom/cal.diy","slug":"bad-request-invalid-url-form-data","errorCode":null,"errorMessage":"Bad Request (Invalid Url Form Data)","messagePattern":"Bad Request \\(Invalid Url Form Data\\)","errorType":"http","errorClass":"HttpError","httpStatus":400,"severity":"warning","filePath":"apps/web/app/api/parseRequestData.ts","lineNumber":16,"sourceCode":"import type { NextRequest } from \"next/server\";\n\nimport { HttpError } from \"@calcom/lib/http-error\";\nimport logger from \"@calcom/lib/logger\";\n\nconst log = logger.getSubLogger({ prefix: [\"[parseRequestData]\"] });\n\nexport async function parseUrlFormData(req: NextRequest): Promise<Record<string, any>> {\n  try {\n    // Read raw text body (because Next.js does NOT parse x-www-form-urlencoded automatically)\n    const rawBody = await req.text();\n    const params = new URLSearchParams(rawBody);\n    return Object.fromEntries(params);\n  } catch (e) {\n    log.error(`Invalid Url Form Data: ${e} from path ${req.nextUrl}`);\n    throw new HttpError({ statusCode: 400, message: \"Bad Request (Invalid Url Form Data)\" });\n  }\n}\n\nexport async function parseMultiFormData(req: NextRequest): Promise<Record<string, any>> {\n  try {\n    const formData = await req.formData();\n    return Object.fromEntries(formData.entries());\n  } catch (e) {\n    log.error(`Invalid Multi Form Data: ${e} from path ${req.nextUrl}`);\n    throw new HttpError({ statusCode: 400, message: \"Bad Request (Invalid Multi Form Data)\" });\n  }\n}\n\nexport async function parseRequestData(req: NextRequest): Promise<Record<string, any>> {\n  const contentType = req.headers.get(\"content-type\") ?? \"application/json\";\n  if (contentType.includes(\"application/json\")) {\n    try {\n      return await req.json();","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/web/app/api/parseRequestData.ts#L1-L34","documentation":"Thrown by parseUrlFormData (HttpError, HTTP 400) when reading req.text() or constructing URLSearchParams for an application/x-www-form-urlencoded body fails. A preceding log.error records the underlying exception and the request path. It indicates the raw body could not be interpreted as URL-encoded form data.","triggerScenarios":"POST with Content-Type application/x-www-form-urlencoded but a malformed body (bad percent-encoding, truncated, binary, or body already consumed by middleware).","commonSituations":"Client sent form data with invalid % sequences, double-read of the body stream, proxy mangling the payload, mismatch between declared content-type and actual body.","solutions":["Validate/encode form fields with encodeURIComponent before submission.","Ensure no middleware consumes req.text()/req.body before parseUrlFormData runs.","Switch to application/json if the payload is structured, to avoid URL-encoding edge cases.","Inspect the logged path and underlying error to pinpoint the malformed segment."],"exampleFix":"// before\nawait fetch('/api/x', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n  body: 'name=' + rawInput, // rawInput may contain '&', '=', '%'\n});\n\n// after\nawait fetch('/api/x', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n  body: new URLSearchParams({ name: rawInput }).toString(),\n});","handlingStrategy":"try-catch","validationCode":"// Encode form fields correctly before sending\nconst body = new URLSearchParams({ name: rawInput }).toString();\nawait fetch('/api/x', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n  body,\n});","typeGuard":"function isUrlEncoded(s: string): boolean {\n  try { new URLSearchParams(s); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await parseUrlFormData(req);\n} catch (e) {\n  if (e instanceof HttpError && e.statusCode === 400) {\n    return Response.json({ error: 'Malformed form data' }, { status: 400 });\n  }\n  throw e;\n}","preventionTips":["Use URLSearchParams/FormData APIs instead of hand-building bodies.","Avoid middleware that consumes req.text() before the parser runs.","Prefer application/json for structured payloads to dodge encoding edge cases."],"tags":["request-parsing","form-data","urlencoded","validation"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}