calcom/cal.diy · warning · HttpError

Bad Request (Invalid Url Form Data)

Error message

Bad Request (Invalid Url Form Data)

What it means

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.

Source

Thrown at apps/web/app/api/parseRequestData.ts:16

import type { NextRequest } from "next/server";

import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";

const log = logger.getSubLogger({ prefix: ["[parseRequestData]"] });

export async function parseUrlFormData(req: NextRequest): Promise<Record<string, any>> {
  try {
    // Read raw text body (because Next.js does NOT parse x-www-form-urlencoded automatically)
    const rawBody = await req.text();
    const params = new URLSearchParams(rawBody);
    return Object.fromEntries(params);
  } catch (e) {
    log.error(`Invalid Url Form Data: ${e} from path ${req.nextUrl}`);
    throw new HttpError({ statusCode: 400, message: "Bad Request (Invalid Url Form Data)" });
  }
}

export async function parseMultiFormData(req: NextRequest): Promise<Record<string, any>> {
  try {
    const formData = await req.formData();
    return Object.fromEntries(formData.entries());
  } catch (e) {
    log.error(`Invalid Multi Form Data: ${e} from path ${req.nextUrl}`);
    throw new HttpError({ statusCode: 400, message: "Bad Request (Invalid Multi Form Data)" });
  }
}

export async function parseRequestData(req: NextRequest): Promise<Record<string, any>> {
  const contentType = req.headers.get("content-type") ?? "application/json";
  if (contentType.includes("application/json")) {
    try {
      return await req.json();

View on GitHub (pinned to 176037d0af)

Solutions

  1. Validate/encode form fields with encodeURIComponent before submission.
  2. Ensure no middleware consumes req.text()/req.body before parseUrlFormData runs.
  3. Switch to application/json if the payload is structured, to avoid URL-encoding edge cases.
  4. Inspect the logged path and underlying error to pinpoint the malformed segment.

Example fix

// before
await fetch('/api/x', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: 'name=' + rawInput, // rawInput may contain '&', '=', '%'
});

// after
await fetch('/api/x', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({ name: rawInput }).toString(),
});
Defensive patterns

Strategy: try-catch

Validate before calling

// Encode form fields correctly before sending
const body = new URLSearchParams({ name: rawInput }).toString();
await fetch('/api/x', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body,
});

Type guard

function isUrlEncoded(s: string): boolean {
  try { new URLSearchParams(s); return true; } catch { return false; }
}

Try / catch

try {
  await parseUrlFormData(req);
} catch (e) {
  if (e instanceof HttpError && e.statusCode === 400) {
    return Response.json({ error: 'Malformed form data' }, { status: 400 });
  }
  throw e;
}

Prevention

When it happens

Trigger: POST with Content-Type application/x-www-form-urlencoded but a malformed body (bad percent-encoding, truncated, binary, or body already consumed by middleware).

Common situations: 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.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/7160975b35fe2d13. Report an issue: GitHub.