{"record":{"id":"903796ebf02a2bff","repo":"ruvnet/ruflo","slug":"buffer-too-small-for-rvfp-preamble","errorCode":null,"errorMessage":"Buffer too small for RVFP preamble","messagePattern":"Buffer too small for RVFP preamble","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts","lineNumber":191,"sourceCode":"      targetApplianceName: opts.targetName, targetApplianceVersion: opts.targetVersion,\n      targetSection: opts.sectionId, patchVersion: opts.patchVersion,\n      created: new Date().toISOString(), newSectionSize: payload.length,\n      newSectionSha256: sha256(payload), compression: comp,\n    };\n    if (opts.privateKey && opts.signedBy) {\n      const signable = Buffer.concat([Buffer.from(canonicalJson(header), 'utf-8'), payload]);\n      header.signature = edSign(signable, opts.privateKey);\n      header.signedBy = opts.signedBy;\n    }\n    const hJson = Buffer.from(JSON.stringify(header), 'utf-8');\n    const magic = Buffer.from('RVFP');\n    const ver = Buffer.alloc(4); ver.writeUInt32LE(RVFP_VERSION, 0);\n    const hLen = Buffer.alloc(4); hLen.writeUInt32LE(hJson.length, 0);\n    return Buffer.concat([magic, ver, hLen, hJson, payload, sha256B(payload)]);\n  }\n\n  static parsePatchHeader(buf: Buffer): RvfpHeader {\n    if (buf.length < PRE) throw new Error('Buffer too small for RVFP preamble');\n    const magic = buf.subarray(0, 4).toString('ascii');\n    if (magic !== 'RVFP') throw new Error(`Invalid RVFP magic: \"${magic}\"`);\n    const ver = buf.readUInt32LE(4);\n    if (ver !== RVFP_VERSION) throw new Error(`Unsupported RVFP version: ${ver}`);\n    const hLen = buf.readUInt32LE(8);\n    if (PRE + hLen > buf.length) throw new Error('Buffer too small for declared header');\n    const h = JSON.parse(buf.subarray(PRE, PRE + hLen).toString('utf-8')) as RvfpHeader;\n    if (h.magic !== 'RVFP') throw new Error('RVFP header magic mismatch');\n    return h;\n  }\n\n  static async verifyPatch(buf: Buffer): Promise<PatchVerifyResult> {\n    const errors: string[] = [];\n    let header: RvfpHeader;\n    try { header = RvfaPatcher.parsePatchHeader(buf); } catch (e) {\n      const empty: RvfpHeader = {\n        magic: 'RVFP', version: 0, targetApplianceName: '', targetApplianceVersion: '',\n        targetSection: '', patchVersion: '', created: '', newSectionSize: 0,","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts#L173-L209","documentation":"RvfaPatcher.parsePatchHeader needs at least the 12-byte preamble (PRE = 4 magic + 4 version + 4 header-length) before it can read anything. This fires when the input is shorter than 12 bytes — an empty or near-empty buffer handed to the parser, typically a failed download saved anyway or a wrong file.","triggerScenarios":"`RvfaPatcher.parsePatchHeader(buf)` or `verifyPatch(buf)` with an empty Buffer (0 bytes), a 1–11 byte stub from an aborted fetch, or a wrongly sliced subarray that trimmed the whole patch away.","commonSituations":"A gateway returned an empty body that was written to disk; reading a path that does not exist and defaulting to an empty buffer; tests feeding truncated fixtures; passing a payload slice instead of the whole patch file.","solutions":["Check buf.length >= 12 before parsing (magic + version + headerLen alone occupy 12 bytes)","Verify the source: stat the downloaded .rvfp and compare with the expected size, or re-fetch it","Confirm you are passing the complete patch file, not a subarray slice of it"],"exampleFix":"// before\nconst header = RvfaPatcher.parsePatchHeader(await readFile(p)); // p empty after a failed fetch\n\n// after\nconst buf = await readFile(p);\nif (buf.length < 12) throw new Error(`Patch too small (${buf.length}B) — re-fetch ${p}`);\nconst header = RvfaPatcher.parsePatchHeader(buf);","handlingStrategy":"validation","validationCode":"const buf = await readFile(patchPath);\nif (buf.length < 12) { // RVFP preamble: 4 magic + 4 version + 4 header_len\n  throw new Error(`Not an RVFP patch (${buf.length} bytes) — re-download`);\n}","typeGuard":"function looksLikeRvfpPatch(buf: Buffer): boolean {\n  return buf.length >= 12 && buf.subarray(0, 4).toString('ascii') === 'RVFP';\n}","tryCatchPattern":null,"preventionTips":["Validate downloaded patches by size and magic bytes before parsing","Use RvfaPatcher.verifyPatch() for untrusted input — it catches header parse errors and reports them in result.errors instead of throwing"],"tags":["rvfa-distribution","rvfp-patch","binary-format","input-validation"],"backgroundTag":"truncated-binary-file","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}