{"record":{"id":"09a97212828a2417","repo":"nexu-io/open-design","slug":"vela-label-wrote-an-empty-output-file","errorCode":null,"errorMessage":"Vela ${label} wrote an empty output file","messagePattern":"Vela (.+?) wrote an empty output file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/vela.ts","lineNumber":123,"sourceCode":"  return model.startsWith('vela/') ? model.slice('vela/'.length) : model;\n}\n\nfunction extensionForImageMime(mime: string): string {\n  if (mime === 'image/jpeg') return '.jpg';\n  if (mime === 'image/webp') return '.webp';\n  if (mime === 'image/png') return '.png';\n  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","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/vela.ts#L105-L141","documentation":"Thrown by readNonEmptyOutput() when the output file exists (stat succeeded) but is not a regular file or has size <= 0. This is distinct from error 487 (file missing): here Vela created something but it carries no bytes, so the artifact is unusable.","triggerScenarios":"Vela wrote the --output path but the file is zero-length, or the path resolves to a directory/pipe/symlink target rather than a regular file.","commonSituations":"Vela CLI created the file then truncated it on a late error; write was interrupted by a kill signal; a broken symlink or named pipe at the output path; filesystem quirk on the temp dir.","solutions":["Retry the request once — partial writes are often transient","Run the Vela command manually and inspect the output file size immediately after","Check for signal-based kills (OOM, timeout) that could truncate the write","Verify the temp directory is on a healthy, non-special filesystem"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"async function isNonEmptyOutputFile(p: string): Promise<boolean> {\n  try {\n    const s = await stat(p);\n    return s.isFile() && s.size > 0;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const bytes = await readNonEmptyOutput(outputPath, label);\n} catch (err) {\n  if (err instanceof Error && /wrote an empty output file/.test(err.message)) {\n    // retry once; if it persists, inspect the vela command for signal kills\n  } else throw err;\n}","preventionTips":["Retry once on empty-output since partial writes are often transient","Ensure the Vela process is not being OOM-killed or timed out mid-write","Log output file size immediately after the Vela command returns to correlate with kills"],"tags":["vela","filesystem","output","empty-file"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}