ruvnet/ruflo · error · Error
Invalid RVFP magic: "${magic}"
Error message
Invalid RVFP magic: "${magic}" What it means
Thrown by parsePatchHeader() when the first 4 bytes of the buffer are not the ASCII string "RVFP". The buffer is long enough to pass the preamble-size check, but its magic bytes identify it as something other than an RVFP patch. This is the format-identity guard that runs after the length check and before the version check.
Source
Thrown at v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts:193
created: new Date().toISOString(), newSectionSize: payload.length,
newSectionSha256: sha256(payload), compression: comp,
};
if (opts.privateKey && opts.signedBy) {
const signable = Buffer.concat([Buffer.from(canonicalJson(header), 'utf-8'), payload]);
header.signature = edSign(signable, opts.privateKey);
header.signedBy = opts.signedBy;
}
const hJson = Buffer.from(JSON.stringify(header), 'utf-8');
const magic = Buffer.from('RVFP');
const ver = Buffer.alloc(4); ver.writeUInt32LE(RVFP_VERSION, 0);
const hLen = Buffer.alloc(4); hLen.writeUInt32LE(hJson.length, 0);
return Buffer.concat([magic, ver, hLen, hJson, payload, sha256B(payload)]);
}
static parsePatchHeader(buf: Buffer): RvfpHeader {
if (buf.length < PRE) throw new Error('Buffer too small for RVFP preamble');
const magic = buf.subarray(0, 4).toString('ascii');
if (magic !== 'RVFP') throw new Error(`Invalid RVFP magic: "${magic}"`);
const ver = buf.readUInt32LE(4);
if (ver !== RVFP_VERSION) throw new Error(`Unsupported RVFP version: ${ver}`);
const hLen = buf.readUInt32LE(8);
if (PRE + hLen > buf.length) throw new Error('Buffer too small for declared header');
const h = JSON.parse(buf.subarray(PRE, PRE + hLen).toString('utf-8')) as RvfpHeader;
if (h.magic !== 'RVFP') throw new Error('RVFP header magic mismatch');
return h;
}
static async verifyPatch(buf: Buffer): Promise<PatchVerifyResult> {
const errors: string[] = [];
let header: RvfpHeader;
try { header = RvfaPatcher.parsePatchHeader(buf); } catch (e) {
const empty: RvfpHeader = {
magic: 'RVFP', version: 0, targetApplianceName: '', targetApplianceVersion: '',
targetSection: '', patchVersion: '', created: '', newSectionSize: 0,
newSectionSha256: '', compression: 'none',
};View on GitHub (pinned to 6b01dc5a68)
Solutions
- Confirm the input is an RVFP patch produced by RvfaPatcher.createPatch().
- If the file is gzipped on disk, gunzip it to a Buffer before parsing.
- Validate the magic bytes (buf.subarray(0,4).equals(Buffer.from('RVFP'))) before calling.
- Re-download or regenerate the patch if the file content is wrong.
Example fix
// before
const header = RvfaPatcher.parsePatchHeader(buf);
// after
if (buf.subarray(0, 4).toString('ascii') !== 'RVFP') {
throw new Error('Input is not an RVFP patch (bad magic)');
}
const header = RvfaPatcher.parsePatchHeader(buf); Defensive patterns
Strategy: validation
Validate before calling
function hasRvfpMagic(buf: Buffer): boolean {
return buf.length >= 4 && buf.subarray(0, 4).toString('ascii') === 'RVFP';
} Type guard
function isRvfpBuffer(buf: unknown): buf is Buffer {
return Buffer.isBuffer(buf) && buf.length >= 4 && buf.subarray(0, 4).toString('ascii') === 'RVFP';
} Try / catch
try {
const header = RvfaPatcher.parsePatchHeader(buf);
} catch (e) {
if (/Invalid RVFP magic/.test((e as Error).message)) {
throw new Error('Input is not an RVFP patch; check that you passed a .rvfp, not a .rvfa');
}
throw e;
} Prevention
- Check the first 4 bytes equal 'RVFP' before calling parsePatchHeader.
- Keep RVFA appliance and RVFP patch handling in distinct code paths.
- Gunzip any gzipped patch transport before parsing.
- Name files with .rvfp extension and validate the extension in pipelines.
When it happens
Trigger: Passing a non-patch buffer (e.g. an RVFA appliance, a gzip stream, a JSON document, or random bytes) to parsePatchHeader/applyPatch/verifyPatch. The first 4 bytes happen not to be 0x52 0x56 0x46 0x50 ('R','V','F','P').
Common situations: Swapping a .rvfa appliance file for a .rvfp patch file in a deploy pipeline; feeding a gzipped patch without first gunzipping; reading a file that was overwritten by a different tool.
Related errors
- Buffer too small for RVFP preamble
- Invalid RVFA magic: expected "RVFA", got "${magic}"
- Unsupported RVFP version: ${ver}
- Buffer too small for declared header
- RVFP header magic mismatch
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/bedb85984a2cfa2f.
Report an issue: GitHub.