{"record":{"id":"27d79c50d7afed6f","repo":"transloadit/uppy","slug":"unexpected-facebook-response-missing-images","errorCode":null,"errorMessage":"Unexpected Facebook response: missing images","messagePattern":"Unexpected Facebook response: missing images","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/companion/src/server/provider/facebook/index.ts","lineNumber":111,"sourceCode":"\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\n}\n\n/**\n * Adapter for API https://developers.facebook.com/docs/graph-api/using-graph-api/\n */\nexport default class Facebook extends Provider<FacebookUserSession> {\n  static override get oauthProvider() {\n    return 'facebook'\n  }\n\n  override async list({\n    directory,\n    providerUserSession: { accessToken: token },\n    query,\n    companion,\n  }: {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/server/provider/facebook/index.ts#L93-L129","documentation":"After fetching a Facebook photo's metadata, Companion filters the body.images array for valid image objects (with a numeric height/width and string source), sorts them, and returns the largest one's URL. If none survive filtering, this error is thrown.","triggerScenarios":"The Facebook response's images field is missing, empty, or contains only entries that fail the isFbImage check (non-string source or non-numeric dimensions) when downloading a Facebook photo via getMediaUrl.","commonSituations":"Facebook changed its response shape for photo objects, the item is a video or album cover with no downloadable images array, or partial/permission-restricted responses return stripped fields.","solutions":["Verify the requested id is a photo (not a video/album) — videos go through a different download path","Re-authenticate to ensure full photo fields are returned","Log and inspect the raw Graph API response for that id (add fields=images to a Graph API explorer query)","If Facebook changed the schema, pin/upgrade Companion to a version tracking the current Graph API"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isFbImageResponse(body: unknown): body is { images: { source: string }[] } {\n  return (\n    typeof body === 'object' && body !== null &&\n    Array.isArray((body as any).images) &&\n    (body as any).images.some((i: any) => typeof i?.source === 'string')\n  )\n}","tryCatchPattern":"try {\n  const url = await getMediaUrl({ secret, token, id })\n} catch (err) {\n  if (err instanceof Error && err.message.includes('missing images')) {\n    return userMessage('No downloadable image found for this item.')\n  }\n  throw err\n}","preventionTips":["Filter Facebook listings to photo-type items before enabling download","Keep Companion updated to track Graph API schema changes","Wrap provider adapters so schema drift degrades gracefully instead of crashing uploads"],"tags":["companion","facebook","graph-api","image"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}