ruvnet/ruflo · error
Buffer too small to be a valid RVFA file
Error message
Buffer too small to be a valid RVFA file
What it means
parseRvfaBinary in rvfa-signing.ts rejects any buffer shorter than 44 bytes (12-byte preamble + 32-byte SHA256 footer) before reading the magic. An RVFA image is at minimum preamble + empty header + footer, so anything smaller cannot be a well-formed file. This is the coarsest gate in the signing/verification path — unlike RvfaReader it reports 'too small' before magic/version checks.
Solutions
- Stat the file before verifying: it must be > 44 bytes and ideally match the expected published size
- Fix the upstream fetch — an empty file almost always means the download failed silently (check HTTP status before writing)
- If writing then verifying in one pipeline, await the write fully (and fsync) before invoking signing APIs
- Add a guard in your code: if (buf.length < 44) skip verification and re-fetch
Example fix
// before — verify whatever landed on disk
const sig = await signer.signFile(await readFile(p));
// after — gate on a plausible minimum size
const buf = await readFile(p);
if (buf.length < 44) throw new Error(`suspect download: ${p} is ${buf.length} bytes`);
const sig = await signer.signFile(buf); Defensive patterns
Strategy: validation
Validate before calling
const MIN = 12 + 32; // preamble + footer
if (buf.length < MIN) throw new Error(`not an RVFA image (${buf.length} bytes)`); Type guard
function isPossiblyRvfa(buf: Buffer): boolean { return buf.length >= 44; } Try / catch
try { await verifyFile(buf, pub); }
catch (e) {
if (/too small to be a valid RVFA/.test(String((e as Error).message))) {
// empty/partial download: re-fetch and check HTTP status before saving
}
throw e;
} Prevention
- Stat files before verifying — flag sizes below 44 bytes as failed downloads
- Check the HTTP status before writing response bodies to disk
- Await writes fully before running signing/verification steps
When it happens
Trigger: Calling signing/verification helpers (e.g. detached-signature computation or verify flows built on parseRvfaBinary) with an empty or near-empty buffer: readFile on a 0-byte file, an empty response body saved as .rvfa, or a placeholder/stub file created before the real download ran.
Common situations: Download pipeline wrote an empty file on a 404/204 and verification ran anyway; touch-ing a placeholder path in a script; race where verification starts before the writer finishes; passing a directory path or /dev/null by configuration mistake.
Related errors
- Header length extends beyond buffer
- Buffer too small to contain declared header
- Failed to parse RVFA header JSON
- Footer hash must be bytes, got
- Invalid RVFA magic: expected "RVFA", got
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/47dd913ce1c99619.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/appliance/rvfa-signing.ts:170
return sorted;
}
return val;
});
}
/**
* Parse an RVFA binary into its components without full validation.
* Returns the header object, header JSON bytes, section data region, and footer.
*/
function parseRvfaBinary(buf: Buffer): {
header: Record<string, unknown>;
headerStart: number;
headerEnd: number;
sectionData: Buffer;
footer: Buffer;
} {
if (buf.length < PREAMBLE_SIZE + SHA256_SIZE) {
throw new Error('Buffer too small to be a valid RVFA file');
}
const magic = buf.subarray(0, 4).toString('ascii');
if (magic !== 'RVFA') {
throw new Error(`Invalid RVFA magic: expected "RVFA", got "${magic}"`);
}
const headerLen = buf.readUInt32LE(8);
const headerStart = PREAMBLE_SIZE;
const headerEnd = headerStart + headerLen;
if (headerEnd > buf.length - SHA256_SIZE) {
throw new Error('Header length extends beyond buffer');
}
const headerJson = buf.subarray(headerStart, headerEnd).toString('utf-8');
let header: Record<string, unknown>;
try {View on GitHub (pinned to fa13ee4ad6)