calcom/cal.diy · warning · HttpError

Invalid request body

Error message

Invalid request body

What it means

Thrown when ZProjectMutationInputSchema.safeParse(req.body) fails - the body must be { projectId: string }. A missing projectId, a non-string value, or an empty body triggers it. Surfaced as HTTP 400.

Source

Thrown at packages/app-store/basecamp3/api/projectMutation.ts:28

import prisma from "@calcom/prisma";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";

interface IDock {
  id: number;
  name: string;
}

const ZProjectMutationInputSchema = z.object({ projectId: z.string() });

async function handler(req: NextApiRequest) {
  const userId = req.session?.user?.id;
  if (!userId) {
    throw new HttpError({ statusCode: 401, message: "Unauthorized" });
  }

  const parsed = ZProjectMutationInputSchema.safeParse(req.body ?? {});
  if (!parsed.success) {
    throw new HttpError({
      statusCode: 400,
      message: "Invalid request body",
    });
  }
  const { projectId } = parsed.data;

  const { user_agent } = await getAppKeysFromSlug("basecamp3");

  const credential = await prisma.credential.findFirst({
    where: { userId },
    select: credentialForCalendarServiceSelect,
  });

  if (!credential) {
    throw new HttpError({ statusCode: 403, message: "No credential found for user" });
  }

  let credentialKey = credential.key as BasecampToken;

View on GitHub (pinned to 176037d0af)

Solutions

  1. Send { projectId: '123' } (string) as a JSON body.
  2. Validate on the client with the same Zod schema before posting.
  3. Ensure the request sets Content-Type: application/json.

Example fix

// before
fetch('/api/integrations/basecamp3/project', { method: 'POST', body: JSON.stringify({ projectId: 123 }) });

// after
fetch('/api/integrations/basecamp3/project', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ projectId: String(123) }),
});
Defensive patterns

Strategy: validation

Validate before calling

const parsed = ZProjectMutationInputSchema.safeParse(req.body ?? {});
if (!parsed.success) {
  // surface parsed.error.issues to the client for a clearer message
}

Type guard

const isProjectIdBody = (b: unknown): b is { projectId: string } =>
  typeof b === 'object' && b !== null && typeof (b as any).projectId === 'string';

Prevention

When it happens

Trigger: POST with no body; projectId sent as a number instead of a string; wrong field name such as project_id; body sent as form-encoded instead of JSON.

Common situations: Frontend form bug omitting projectId; client serializing the field under a different key; missing Content-Type: application/json header.

Related errors


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