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. AView on GitHub (pinned to 5be4028344)
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
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
- 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
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
- Vela ${label} did not write the requested output file
- invalid brand id: ${id}
- invalid brand id: ${id}
- brand.json not found for brand "${id}"
- authorized pull receipt has invalid ${key}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/09a97212828a2417.
Report an issue: GitHub.