{"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":"Error","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/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts#L173-L209","documentation":"Thrown by RvfaPatcher.parsePatchHeader() when an RVFP patch buffer is under PRE (12) bytes — too short to contain the 4-byte magic, 4-byte version, and 4-byte header-length fields. It is the first structural check before any field is read, so it fires before magic/version errors. The companion applyPatch() and verifyPatch() both call parsePatchHeader, so a malformed patch surfaces here.","triggerScenarios":"Passing an empty or near-empty Buffer to parsePatchHeader, applyPatch, or verifyPatch. Passing a truncated file body, a directory listing, or a Buffer allocated but never written. Reading a .rvfp file that was only partially downloaded.","commonSituations":"Incomplete IPFS fetch of a patch, a zero-byte patch file left by a failed write, or mistakenly passing an RVFA appliance buffer where an RVFP patch was expected (the appliance is large, so this usually passes the 12-byte check — the mismatch surfaces later as a magic error instead).","solutions":["Verify the patch file size is well above 12 bytes before parsing.","Re-fetch the patch from IPFS if the download was interrupted.","Confirm you are reading a .rvfp patch, not a .rvfa appliance or unrelated file.","Check stat().size of the patch file and reject early if it is below the minimum."],"exampleFix":"// before\nconst header = RvfaPatcher.parsePatchHeader(buf); // buf may be empty/truncated\n\n// after\nif (buf.length < 12) throw new Error(`Patch file too small (${buf.length}B), expected a valid .rvfp`);\nconst header = RvfaPatcher.parsePatchHeader(buf);","handlingStrategy":"validation","validationCode":"const RVFP_PRE = 12;\nfunction isPatchSized(buf: Buffer): boolean {\n  return Buffer.isBuffer(buf) && buf.length >= RVFP_PRE;\n}","typeGuard":"function isRvfpCandidate(buf: unknown): buf is Buffer {\n  return Buffer.isBuffer(buf) && buf.length >= 12;\n}","tryCatchPattern":"try {\n  const header = RvfaPatcher.parsePatchHeader(buf);\n} catch (e) {\n  if (/Buffer too small for RVFP preamble/.test((e as Error).message)) {\n    throw new Error(`Patch file is ${buf.length} bytes; expected a valid .rvfp >= 12 bytes`);\n  }\n  throw e;\n}","preventionTips":["stat() patch files and reject those below 12 bytes before reading.","Verify downloads completed (compare bytes-received vs content-length).","Keep patch files and appliance files in separate directories to avoid confusion.","Log the expected patch size from the producer for round-trip validation."],"tags":["rvfp","buffer","validation","binary-format"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}