{"record":{"id":"9e15d17d3358a78f","repo":"nexu-io/open-design","slug":"image-too-large-info-size-bytes-max-max-i","errorCode":null,"errorMessage":"--image too large (${info.size} bytes; max ${MAX_IMAGE_BYTES}).","messagePattern":"--image too large \\((.+?) bytes; max (.+?)\\)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/daemon/src/media/index.ts","lineNumber":245,"sourceCode":"      `--image path \"${rel}\" resolves outside the project directory.`,\n    );\n  }\n  let info;\n  try {\n    info = await stat(abs);\n  } catch {\n    throw new Error(`--image not found: ${rel}`);\n  }\n  if (!info.isFile()) {\n    throw new Error(`--image is not a regular file: ${rel}`);\n  }\n  // Cap at 16 MB. Beyond this, base64 inflation alone (≈4/3) starts\n  // hitting body-size limits at the upstream APIs and our own express\n  // 4mb body cap on inbound requests; bigger payloads should travel\n  // via the dedicated upload endpoint, not the dispatcher.\n  const MAX_IMAGE_BYTES = 16 * 1024 * 1024;\n  if (info.size > MAX_IMAGE_BYTES) {\n    throw new Error(\n      `--image too large (${info.size} bytes; max ${MAX_IMAGE_BYTES}).`,\n    );\n  }\n  const bytes = await readFile(abs);\n  const ext = path.extname(abs).toLowerCase();\n  // Tight allowlist: only what i2v / image-edit endpoints actually\n  // consume. Avoids smuggling arbitrary content through as data URLs.\n  const mime = ({\n    '.png': 'image/png',\n    '.jpg': 'image/jpeg',\n    '.jpeg': 'image/jpeg',\n    '.webp': 'image/webp',\n    '.gif': 'image/gif',\n  })[ext];\n  if (!mime) {\n    throw new Error(\n      `--image has unsupported extension \"${ext}\". Use png, jpg, jpeg, webp, or gif.`,\n    );","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L227-L263","documentation":"Thrown by resolveProjectImage when the regular file exceeds MAX_IMAGE_BYTES (16 MB). The cap exists because base64 inflation (~4/3) plus the upstream API and the daemon's own ~4 MB inbound body cap would reject larger payloads anyway; oversized images must use the dedicated upload endpoint instead of the inline --image dispatcher.","triggerScenarios":"Attaching a high-resolution photo, screenshot, or rendered frame larger than 16 MB; uncompressed PNG/TIFF exports; a generated image pipeline outputting oversized frames.","commonSituations":"Print-resolution assets; raw camera exports; lossless screen captures; multi-frame/animated content exported as a single large file.","solutions":["Resize/recompress the image to bring it under 16 MB (e.g. lower resolution, JPEG quality, or PNG optimization).","Use the dedicated media upload endpoint for large assets instead of inline --image.","Strip unnecessary metadata/exif that inflates size.","Prefer WebP/JPEG over uncompressed formats for photographic content."],"exampleFix":"// before: 30 MB screenshot\n--image assets/full.png\n// after: compress to < 16 MB\nsharp('assets/full.png').resize({ width: 2000 }).jpeg({ quality: 85 }).toFile('assets/full.jpg')\n--image assets/full.jpg","handlingStrategy":"validation","validationCode":"const MAX = 16 * 1024 * 1024;\nif (info.size > MAX) throw new Error(`--image too large (${info.size}); compress or use upload endpoint`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compress/resize images below 16 MB before dispatch.","Use the dedicated upload endpoint for large assets.","Strip metadata that bloats file size."],"tags":["media","validation","size-limit","performance"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}