nexu-io/open-design · error · Error

Vela media accepts at most ${VELA_MAX_INPUT_IMAGES} input im

Error message

Vela media accepts at most ${VELA_MAX_INPUT_IMAGES} input images; received ${imageRefs.length}

What it means

Thrown by assertInputImageCount() when more than VELA_MAX_INPUT_IMAGES (5) image references are passed to a Vela render. The guard fires at the very top of renderVelaImage and renderVelaVideo, before any catalogue read or CLI spawn, so the caller is told the limit before incurring cost.

Source

Thrown at apps/daemon/src/media/vela.ts:130

  throw new Error(`Vela image returned unsupported mime_type ${mime}`);
}

async function readNonEmptyOutput(outputPath: string, label: string): Promise<Buffer> {
  let outputStat;
  try {
    outputStat = await stat(outputPath);
  } catch {
    throw new Error(`Vela ${label} did not write the requested output file`);
  }
  if (!outputStat.isFile() || outputStat.size <= 0) {
    throw new Error(`Vela ${label} wrote an empty output file`);
  }
  return readFile(outputPath);
}

function assertInputImageCount(imageRefs: VelaMediaImageRef[]): void {
  if (imageRefs.length > VELA_MAX_INPUT_IMAGES) {
    throw new Error(
      `Vela media accepts at most ${VELA_MAX_INPUT_IMAGES} input images; received ${imageRefs.length}`,
    );
  }
}

async function stageInputImages(
  imageRefs: VelaMediaImageRef[],
  tempDir: string,
): Promise<VelaMediaImageRef[]> {
  return Promise.all(imageRefs.map(async (image, index) => {
    // Vela CLI may downscale oversized references in place before upload. A
    // project file is user data and also participates in the daemon's artifact
    // diff, so never let a transport optimization mutate the source or make an
    // untouched reference appear as this run's output.
    const extension = path.extname(image.abs);
    const staged = path.join(tempDir, `input-${index + 1}${extension}`);
    await copyFile(image.abs, staged);
    return { abs: staged };

View on GitHub (pinned to 5be4028344)

Solutions

  1. Reduce the number of input images to 5 or fewer before calling render
  2. Enforce the VELA_MAX_INPUT_IMAGES limit in the UI/agent layer before submission
  3. If more references are genuinely needed, request a limit bump from Vela and update the constant

Example fix

// before
const refs = images.slice(0, 10).map(abs => ({ abs }));
await renderVelaImage({ ...input, imageRefs: refs });
// after
const MAX = 5;
const refs = images.slice(0, MAX).map(abs => ({ abs }));
await renderVelaImage({ ...input, imageRefs: refs });
Defensive patterns

Strategy: validation

Validate before calling

const VELA_MAX_INPUT_IMAGES = 5;

function withinImageLimit(refs: VelaMediaImageRef[]): boolean {
  return refs.length <= VELA_MAX_INPUT_IMAGES;
}

if (!withinImageLimit(imageRefs)) {
  throw new Error(`Trim input images to at most ${VELA_MAX_INPUT_IMAGES}`);
}

Type guard

function isWithinVelaImageLimit(refs: unknown[]): boolean {
  return Array.isArray(refs) && refs.length <= 5;
}

Prevention

When it happens

Trigger: Passing a VelaMediaImageRef[] with length > 5 as input.imageRefs to renderVelaImage or renderVelaVideo. Each ref is a staged input image (first-frame or edit references).

Common situations: UI or agent attached too many reference images; batch-attachment UI did not enforce the limit; caller assumed a higher limit than Vela supports.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/bed63cf4d761f0c2. Report an issue: GitHub.