transloadit/uppy · error · Error

Unexpected Facebook response: missing body

Error message

Unexpected Facebook response: missing body

What it means

Facebook's Graph API batch endpoint returns an array of per-request results. When fetching a photo's media URL via a batch request, if the first batch result is missing (empty array), Companion throws this error because there is no body to read the images list from.

Solutions

  1. Have the user re-authenticate Facebook with the required user_photos/photos permission granted
  2. Verify the item still exists (open it on Facebook) — deleted items cannot be downloaded
  3. Check the Facebook app's App Review status for photos permission if other users are affected
  4. Catch and surface a friendly 'file no longer available' message in your UI
Defensive patterns

Strategy: try-catch

Type guard

function hasBatchBody(batch: unknown[]): batch is [{ body: unknown }] {
  return Array.isArray(batch) && batch.length > 0 && 'body' in (batch[0] ?? {})
}

Try / catch

try {
  const url = await provider.url({ id, token })
} catch (err) {
  if (err instanceof Error && err.message.includes('missing body')) {
    return userMessage('This Facebook file is no longer available.')
  }
  throw err
}

Prevention

When it happens

Trigger: Calling the Facebook provider's download/url flow for a photo whose batch request returned zero results — typically a permissions change, the item was deleted, the access token lost user_photos scope, or Facebook returned an error-only batch response.

Common situations: Facebook app permissions changed after users connected (missing user_photos), the photo/album was deleted between listing and downloading, or an expired/invalidated access token causing Facebook to return an empty or error batch.

Related errors


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

Appendix: source

Thrown at packages/@uppy/companion/src/server/provider/facebook/index.ts:95

  id,
}: {
  secret: string
  token: string
  id: string
}): Promise<string> {
  const batch = await runRequestBatch({
    secret,
    token,
    requests: [
      {
        method: 'GET',
        relative_url: `${id}?${new URLSearchParams({ fields: 'images' }).toString()}`,
      },
    ],
  })

  const first = batch[0]
  if (!first) throw new Error('Unexpected Facebook response: missing body')
  const body = first.body

  const imagesValue = isRecord(body) ? body['images'] : undefined

  const isFbImage = (
    value: unknown,
  ): value is { width: number; source: string } =>
    isRecord(value) &&
    typeof value['width'] === 'number' &&
    typeof value['source'] === 'string'

  const images = Array.isArray(imagesValue) ? imagesValue.filter(isFbImage) : []
  const sortedImages = sortImages(images)
  const largest = sortedImages[sortedImages.length - 1]
  if (!largest) {
    throw new Error('Unexpected Facebook response: missing images')
  }
  return largest.source

View on GitHub (pinned to 5d4dedd02a)