{"record":{"id":"8ef511f7f032fd29","repo":"vercel/ai","slug":"luma-ai-character-supports-up-to-4-images-per-iden","errorCode":null,"errorMessage":"Luma AI character supports up to 4 images per identity. Identity '${identityId}' has ${images.length} images.","messagePattern":"Luma AI character supports up to 4 images per identity\\. Identity '(.+?)' has (.+?) images\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/luma/src/luma-image-model.ts","lineNumber":305,"sourceCode":"        break;\n      }\n\n      case 'character': {\n        // Group images by identity id\n        const identities: Record<string, string[]> = {};\n        for (let i = 0; i < files.length; i++) {\n          const file = files[i] as { type: 'url'; url: string };\n          const identityId = imageConfigs[i]?.id ?? 'identity0';\n          if (!identities[identityId]) {\n            identities[identityId] = [];\n          }\n          identities[identityId].push(file.url);\n        }\n\n        // Validate each identity has at most 4 images\n        for (const [identityId, images] of Object.entries(identities)) {\n          if (images.length > 4) {\n            throw new Error(\n              `Luma AI character supports up to 4 images per identity. ` +\n                `Identity '${identityId}' has ${images.length} images.`,\n            );\n          }\n        }\n\n        options.character = Object.fromEntries(\n          Object.entries(identities).map(([id, images]) => [id, { images }]),\n        );\n        break;\n      }\n\n      case 'modify_image': {\n        // Only supports a single image\n        if (files.length > 1) {\n          throw new Error(\n            'Luma AI modify_image only supports a single input image. ' +\n              `You provided ${files.length} images.`,","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/luma/src/luma-image-model.ts#L287-L323","documentation":"Thrown by getEditingOptions when a 'character' reference identity contains more than 4 images. Luma's character feature builds a consistent identity from up to 4 images per identity, so the SDK validates each identity's image count client-side and includes the offending identityId in the message.","triggerScenarios":"Calling generateImage with a luma image model using character references where one character id has 5+ associated images in prompt.images (images grouped by id/identity).","commonSituations":"Feeding an entire photo album of a person/character as one identity; dynamic pipelines where user-uploaded images accumulate per identity without a cap; mislabeling images so several characters' photos land under a single identity id.","solutions":["Trim the offending identity's images to at most 4 of the most representative shots.","Split excess images into separate character identities (distinct ids) if they depict different subjects.","Curate identity images beforehand (dedupe similar frames) and enforce a 4-image cap in your upload UI.","Verify identity id assignment so images are not accidentally grouped under one id."],"exampleFix":"// before\nimages: [{ id: 'hero', url: u1 }, { id: 'hero', url: u2 }, { id: 'hero', url: u3 }, { id: 'hero', url: u4 }, { id: 'hero', url: u5 }]\n// after\nimages: [{ id: 'hero', url: u1 }, { id: 'hero', url: u2 }, { id: 'hero', url: u3 }, { id: 'hero', url: u4 }]","handlingStrategy":"validation","validationCode":"const byIdentity = {};\nfor (const img of images ?? []) {\n  (byIdentity[img.id ?? 'default'] ||= []).push(img);\n}\nfor (const [id, imgs] of Object.entries(byIdentity)) {\n  if (imgs.length > 4) throw new Error(`Identity '${id}' exceeds Luma's 4-image character limit`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await generateImage({ model: lumaImage, prompt });\n} catch (e) {\n  const m = e instanceof Error && e.message.match(/Identity '(\\S+)' has (\\d+) images/);\n  if (m) {\n    const capped = capIdentityImages(prompt.images, m[1], 4);\n    return generateImage({ model: lumaImage, prompt: { ...prompt, images: capped } });\n  }\n  throw e;\n}","preventionTips":["Enforce a 4-image cap per character identity in your upload flow.","Curate the most representative identity images (dedupe similar shots).","Verify identity id grouping before submission so subjects are not merged.","Add tests that group images by id and assert the <=4 invariant."],"tags":["validation","image-limits","character-reference","luma"],"backgroundTag":"provider-limit-exceeded","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}