ruvnet/ruflo · error · Error

Buffer too small for RVFP preamble

Error message

Buffer too small for RVFP preamble

What it means

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.

Source

Thrown at v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts:191

      targetApplianceName: opts.targetName, targetApplianceVersion: opts.targetVersion,
      targetSection: opts.sectionId, patchVersion: opts.patchVersion,
      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,

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Verify the patch file size is well above 12 bytes before parsing.
  2. Re-fetch the patch from IPFS if the download was interrupted.
  3. Confirm you are reading a .rvfp patch, not a .rvfa appliance or unrelated file.
  4. Check stat().size of the patch file and reject early if it is below the minimum.

Example fix

// before
const header = RvfaPatcher.parsePatchHeader(buf); // buf may be empty/truncated

// after
if (buf.length < 12) throw new Error(`Patch file too small (${buf.length}B), expected a valid .rvfp`);
const header = RvfaPatcher.parsePatchHeader(buf);
Defensive patterns

Strategy: validation

Validate before calling

const RVFP_PRE = 12;
function isPatchSized(buf: Buffer): boolean {
  return Buffer.isBuffer(buf) && buf.length >= RVFP_PRE;
}

Type guard

function isRvfpCandidate(buf: unknown): buf is Buffer {
  return Buffer.isBuffer(buf) && buf.length >= 12;
}

Try / catch

try {
  const header = RvfaPatcher.parsePatchHeader(buf);
} catch (e) {
  if (/Buffer too small for RVFP preamble/.test((e as Error).message)) {
    throw new Error(`Patch file is ${buf.length} bytes; expected a valid .rvfp >= 12 bytes`);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/903796ebf02a2bff. Report an issue: GitHub.