{"record":{"id":"3c572e9be6219bc3","repo":"transloadit/uppy","slug":"unexpected-facebook-response-missing-body","errorCode":null,"errorMessage":"Unexpected Facebook response: missing body","messagePattern":"Unexpected Facebook response: missing body","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/companion/src/server/provider/facebook/index.ts","lineNumber":95,"sourceCode":"  id,\n}: {\n  secret: string\n  token: string\n  id: string\n}): Promise<string> {\n  const batch = await runRequestBatch({\n    secret,\n    token,\n    requests: [\n      {\n        method: 'GET',\n        relative_url: `${id}?${new URLSearchParams({ fields: 'images' }).toString()}`,\n      },\n    ],\n  })\n\n  const first = batch[0]\n  if (!first) throw new Error('Unexpected Facebook response: missing body')\n  const body = first.body\n\n  const imagesValue = isRecord(body) ? body['images'] : undefined\n\n  const isFbImage = (\n    value: unknown,\n  ): value is { width: number; source: string } =>\n    isRecord(value) &&\n    typeof value['width'] === 'number' &&\n    typeof value['source'] === 'string'\n\n  const images = Array.isArray(imagesValue) ? imagesValue.filter(isFbImage) : []\n  const sortedImages = sortImages(images)\n  const largest = sortedImages[sortedImages.length - 1]\n  if (!largest) {\n    throw new Error('Unexpected Facebook response: missing images')\n  }\n  return largest.source","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/server/provider/facebook/index.ts#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Have the user re-authenticate Facebook with the required user_photos/photos permission granted","Verify the item still exists (open it on Facebook) — deleted items cannot be downloaded","Check the Facebook app's App Review status for photos permission if other users are affected","Catch and surface a friendly 'file no longer available' message in your UI"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasBatchBody(batch: unknown[]): batch is [{ body: unknown }] {\n  return Array.isArray(batch) && batch.length > 0 && 'body' in (batch[0] ?? {})\n}","tryCatchPattern":"try {\n  const url = await provider.url({ id, token })\n} catch (err) {\n  if (err instanceof Error && err.message.includes('missing body')) {\n    return userMessage('This Facebook file is no longer available.')\n  }\n  throw err\n}","preventionTips":["Handle provider download failures gracefully in the Dashboard UI","Refresh provider listings before long-lived sessions to drop deleted items","Require re-auth when Graph API permission errors cluster"],"tags":["companion","facebook","graph-api","batch-request"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}