{"record":{"id":"bed63cf4d761f0c2","repo":"nexu-io/open-design","slug":"vela-media-accepts-at-most-vela-max-input-images","errorCode":null,"errorMessage":"Vela media accepts at most ${VELA_MAX_INPUT_IMAGES} input images; received ${imageRefs.length}","messagePattern":"Vela media accepts at most (.+?) input images; received (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/vela.ts","lineNumber":130,"sourceCode":"  throw new Error(`Vela image returned unsupported mime_type ${mime}`);\n}\n\nasync function readNonEmptyOutput(outputPath: string, label: string): Promise<Buffer> {\n  let outputStat;\n  try {\n    outputStat = await stat(outputPath);\n  } catch {\n    throw new Error(`Vela ${label} did not write the requested output file`);\n  }\n  if (!outputStat.isFile() || outputStat.size <= 0) {\n    throw new Error(`Vela ${label} wrote an empty output file`);\n  }\n  return readFile(outputPath);\n}\n\nfunction assertInputImageCount(imageRefs: VelaMediaImageRef[]): void {\n  if (imageRefs.length > VELA_MAX_INPUT_IMAGES) {\n    throw new Error(\n      `Vela media accepts at most ${VELA_MAX_INPUT_IMAGES} input images; received ${imageRefs.length}`,\n    );\n  }\n}\n\nasync function stageInputImages(\n  imageRefs: VelaMediaImageRef[],\n  tempDir: string,\n): Promise<VelaMediaImageRef[]> {\n  return Promise.all(imageRefs.map(async (image, index) => {\n    // Vela CLI may downscale oversized references in place before upload. A\n    // project file is user data and also participates in the daemon's artifact\n    // diff, so never let a transport optimization mutate the source or make an\n    // untouched reference appear as this run's output.\n    const extension = path.extname(image.abs);\n    const staged = path.join(tempDir, `input-${index + 1}${extension}`);\n    await copyFile(image.abs, staged);\n    return { abs: staged };","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/vela.ts#L112-L148","documentation":"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.","triggerScenarios":"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).","commonSituations":"UI or agent attached too many reference images; batch-attachment UI did not enforce the limit; caller assumed a higher limit than Vela supports.","solutions":["Reduce the number of input images to 5 or fewer before calling render","Enforce the VELA_MAX_INPUT_IMAGES limit in the UI/agent layer before submission","If more references are genuinely needed, request a limit bump from Vela and update the constant"],"exampleFix":"// before\nconst refs = images.slice(0, 10).map(abs => ({ abs }));\nawait renderVelaImage({ ...input, imageRefs: refs });\n// after\nconst MAX = 5;\nconst refs = images.slice(0, MAX).map(abs => ({ abs }));\nawait renderVelaImage({ ...input, imageRefs: refs });","handlingStrategy":"validation","validationCode":"const VELA_MAX_INPUT_IMAGES = 5;\n\nfunction withinImageLimit(refs: VelaMediaImageRef[]): boolean {\n  return refs.length <= VELA_MAX_INPUT_IMAGES;\n}\n\nif (!withinImageLimit(imageRefs)) {\n  throw new Error(`Trim input images to at most ${VELA_MAX_INPUT_IMAGES}`);\n}","typeGuard":"function isWithinVelaImageLimit(refs: unknown[]): boolean {\n  return Array.isArray(refs) && refs.length <= 5;\n}","tryCatchPattern":null,"preventionTips":["Enforce the 5-image limit in the UI attachment flow, not only at the render boundary","Slice the incoming image list to the limit before constructing the render input","Add a constant export so callers reference the same limit value"],"tags":["vela","validation","input","limits"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}