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
- Ensure the client uses @uppy/google-drive (or companion-client) of a matching version as the Companion server
- Send the exact expected body: { accessToken: string, platform: 'photos'|'drive', ... } as application/json
- 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
- Pin @uppy/companion and client packages to matching versions
- Always send Content-Type: application/json
- Read the zod schema in companion source when integrating manually
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
- region must be a string
- Missing S3 object key for aborting upload
- Missing S3 object key for resuming upload
- Missing S3 object key for uploading part
- companionEndpoint must be a string
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/ac72019c6703c6c8.
Report an issue: GitHub.