transloadit/uppy · warning

Invalid request body

Error message

Invalid request body

What it means

Companion's Google Picker import endpoint validates req.body against googlePickerBodySchema (zod). On parse failure it immediately responds 400 'Invalid request body', meaning the payload doesn't match the expected shape (accessToken, platform, etc.).

Source

Thrown at packages/@uppy/companion/src/server/controllers/googlePicker.ts:36

    accessToken: z.string().min(1),
    fileId: z.string().min(1),
  }),
  z.object({
    platform: z.literal('photos'),
    accessToken: z.string().min(1),
    url: z.string().min(1),
  }),
])

const get = async (req: Request, res: Response): Promise<void> => {
  try {
    logger.debug('Google Picker file import handler running', undefined, req.id)

    const allowLocalUrls = false

    const parsedBody = googlePickerBodySchema.safeParse(req.body)
    if (!parsedBody.success) {
      res.status(400).json({ error: 'Invalid request body' })
      return
    }
    const { accessToken, platform } = parsedBody.data

    if (
      platform === 'photos' &&
      !validateURL(parsedBody.data.url, allowLocalUrls)
    ) {
      res.status(400).json({ error: 'Invalid URL' })
      return
    }

    const download = () => {
      if (platform === 'drive') {
        return streamGoogleFile({
          token: accessToken,
          id: parsedBody.data.fileId,
        })

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Ensure the client uses @uppy/google-drive (or companion-client) of a matching version as the Companion server
  2. Send the exact expected body: { accessToken: string, platform: 'photos'|'drive', ... } as application/json
  3. Inspect the zod schema in companion source (googlePickerBodySchema) for the authoritative field list

Example fix

// before
fetch('/companion/google-picker', {
  method: 'POST',
  body: JSON.stringify({ token: accessToken }),
})

// after
fetch('/companion/google-picker', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ accessToken, platform: 'drive' }),
})
Defensive patterns

Strategy: validation

Validate before calling

const body = { accessToken: token, platform: 'drive' }
if (typeof body.accessToken === 'string' && body.accessToken && ['drive','photos'].includes(body.platform)) {
  await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
}

Type guard

const isValidPickerBody = (b: unknown): b is { accessToken: string; platform: 'drive' | 'photos' } =>
  typeof b === 'object' && b !== null &&
  typeof (b as any).accessToken === 'string' && (b as any).accessToken.length > 0 &&
  ['drive', 'photos'].includes((b as any).platform)

Prevention

When it happens

Trigger: POSTing to the google-picker endpoint with missing/incorrectly-typed fields — e.g. missing accessToken, platform not in the allowed enum ('photos' vs 'drive'), or a malformed JSON body.

Common situations: Client/version mismatch after upgrading @uppy/companion or companion-client (schema changed), hand-rolled fetch calls to the endpoint, or proxies stripping/mangling the JSON body.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/ac72019c6703c6c8. Report an issue: GitHub.