vercel/ai · error · Error

Luma AI character supports up to 4 images per identity. Iden

Error message

Luma AI character supports up to 4 images per identity. Identity '${identityId}' has ${images.length} images.

What it means

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.

Source

Thrown at packages/luma/src/luma-image-model.ts:305

        break;
      }

      case 'character': {
        // Group images by identity id
        const identities: Record<string, string[]> = {};
        for (let i = 0; i < files.length; i++) {
          const file = files[i] as { type: 'url'; url: string };
          const identityId = imageConfigs[i]?.id ?? 'identity0';
          if (!identities[identityId]) {
            identities[identityId] = [];
          }
          identities[identityId].push(file.url);
        }

        // Validate each identity has at most 4 images
        for (const [identityId, images] of Object.entries(identities)) {
          if (images.length > 4) {
            throw new Error(
              `Luma AI character supports up to 4 images per identity. ` +
                `Identity '${identityId}' has ${images.length} images.`,
            );
          }
        }

        options.character = Object.fromEntries(
          Object.entries(identities).map(([id, images]) => [id, { images }]),
        );
        break;
      }

      case 'modify_image': {
        // Only supports a single image
        if (files.length > 1) {
          throw new Error(
            'Luma AI modify_image only supports a single input image. ' +
              `You provided ${files.length} images.`,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Trim the offending identity's images to at most 4 of the most representative shots.
  2. Split excess images into separate character identities (distinct ids) if they depict different subjects.
  3. Curate identity images beforehand (dedupe similar frames) and enforce a 4-image cap in your upload UI.
  4. Verify identity id assignment so images are not accidentally grouped under one id.

Example fix

// before
images: [{ id: 'hero', url: u1 }, { id: 'hero', url: u2 }, { id: 'hero', url: u3 }, { id: 'hero', url: u4 }, { id: 'hero', url: u5 }]
// after
images: [{ id: 'hero', url: u1 }, { id: 'hero', url: u2 }, { id: 'hero', url: u3 }, { id: 'hero', url: u4 }]
Defensive patterns

Strategy: validation

Validate before calling

const byIdentity = {};
for (const img of images ?? []) {
  (byIdentity[img.id ?? 'default'] ||= []).push(img);
}
for (const [id, imgs] of Object.entries(byIdentity)) {
  if (imgs.length > 4) throw new Error(`Identity '${id}' exceeds Luma's 4-image character limit`);
}

Try / catch

try {
  await generateImage({ model: lumaImage, prompt });
} catch (e) {
  const m = e instanceof Error && e.message.match(/Identity '(\S+)' has (\d+) images/);
  if (m) {
    const capped = capIdentityImages(prompt.images, m[1], 4);
    return generateImage({ model: lumaImage, prompt: { ...prompt, images: capped } });
  }
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/8ef511f7f032fd29. Report an issue: GitHub.