nexu-io/open-design · error · Error

Vela ${label} wrote an empty output file

Error message

Vela ${label} wrote an empty output file

What it means

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.

Source

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

  return model.startsWith('vela/') ? model.slice('vela/'.length) : model;
}

function extensionForImageMime(mime: string): string {
  if (mime === 'image/jpeg') return '.jpg';
  if (mime === 'image/webp') return '.webp';
  if (mime === 'image/png') return '.png';
  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

View on GitHub (pinned to 5be4028344)

Solutions

  1. Retry the request once — partial writes are often transient
  2. Run the Vela command manually and inspect the output file size immediately after
  3. Check for signal-based kills (OOM, timeout) that could truncate the write
  4. Verify the temp directory is on a healthy, non-special filesystem
Defensive patterns

Strategy: retry

Validate before calling

async function isNonEmptyOutputFile(p: string): Promise<boolean> {
  try {
    const s = await stat(p);
    return s.isFile() && s.size > 0;
  } catch { return false; }
}

Try / catch

try {
  const bytes = await readNonEmptyOutput(outputPath, label);
} catch (err) {
  if (err instanceof Error && /wrote an empty output file/.test(err.message)) {
    // retry once; if it persists, inspect the vela command for signal kills
  } else throw err;
}

Prevention

When it happens

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

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

Related errors


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