{"record":{"id":"2048148d6c7d0122","repo":"ruvnet/ruflo","slug":"buffer-too-small-to-contain-declared-header","errorCode":null,"errorMessage":"Buffer too small to contain declared header","messagePattern":"Buffer too small to contain declared header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-format.ts","lineNumber":337,"sourceCode":"    }\n\n    // Version\n    const version = buf.readUInt32LE(MAGIC_SIZE);\n    if (version !== RVFA_VERSION) {\n      throw new Error(\n        `Unsupported RVFA version: ${version} (expected ${RVFA_VERSION})`,\n      );\n    }\n\n    // Header length\n    const headerLen = buf.readUInt32LE(MAGIC_SIZE + VERSION_SIZE);\n    if (headerLen > MAX_HEADER_JSON_SIZE) {\n      throw new Error(\n        `Header JSON exceeds maximum size (${headerLen} > ${MAX_HEADER_JSON_SIZE})`,\n      );\n    }\n    if (PREAMBLE_SIZE + headerLen > buf.length) {\n      throw new Error('Buffer too small to contain declared header');\n    }\n\n    // Parse header JSON\n    const headerSlice = buf.subarray(PREAMBLE_SIZE, PREAMBLE_SIZE + headerLen);\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(headerSlice.toString('utf-8'));\n    } catch {\n      throw new Error('Failed to parse RVFA header JSON');\n    }\n\n    if (!validateHeader(parsed)) {\n      throw new Error('RVFA header failed validation');\n    }\n    const header = parsed as RvfaHeader;\n\n    // Bounds-check every section offset\n    const totalSize = buf.length;","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-format.ts#L319-L355","documentation":"Thrown by RvfaReader.fromBuffer when the u32LE header length stored at byte offset 8 (after the 4-byte 'RVFA' magic and 4-byte version) plus the 12-byte preamble exceeds the actual buffer length. The RVFA format declares its JSON header size up front; if the file is truncated or the length field is corrupt, the declared header cannot physically fit and the reader aborts before attempting to parse JSON. This is a hard integrity check — the reader never clamps or guesses.","triggerScenarios":"Calling RvfaReader.fromBuffer(buf) or await RvfaReader.fromFile(path) where readUInt32LE(8) + 12 > buf.length. Concretely: a partially downloaded .rvfa image, a file cut short by a disk-full write, or a hand-assembled buffer whose headerLen field doesn't match the JSON bytes actually appended.","commonSituations":"Interrupted scp/cp or CI artifact size limits truncating the image; disk-full during appliance build; test fixtures that write the preamble but forget to append the header JSON; a length field written in the wrong endianness or at the wrong offset by custom tooling.","solutions":["Verify the file size against the source and re-download/rebuild — truncation is the most common cause; confirm the 32-byte SHA256 footer is actually present at the end","Inspect the preamble: buf.readUInt32LE(8) must be <= buf.length - 12 - 32; if it is enormous, the length field itself is corrupt and the file is unrecoverable","If you generate RVFA buffers yourself, write headerLen as the exact byte length of the serialized JSON header (see exampleFix)","Check transfer integrity with checksums (rsync -c, sha256sum on both ends) before retrying"],"exampleFix":"// before — declared length doesn't match the JSON actually written\nconst headerJson = Buffer.from(JSON.stringify(header));\npreamble.writeUInt32LE(headerJson.length + 64, 8); // padded guess -> truncation read-back\n\n// after — declare the exact JSON byte length\nconst headerJson = Buffer.from(JSON.stringify(header));\npreamble.writeUInt32LE(headerJson.length, 8);\nconst image = Buffer.concat([preamble, headerJson, sectionData, footer]);","handlingStrategy":"validation","validationCode":"import { RVFA_MAGIC, RVFA_VERSION } from './rvfa-format.js';\n\nfunction canContainHeader(buf: Buffer): boolean {\n  if (buf.length < 44) return false;\n  if (!buf.subarray(0, 4).equals(RVFA_MAGIC)) return false;\n  if (buf.readUInt32LE(4) !== RVFA_VERSION) return false;\n  const headerLen = buf.readUInt32LE(8);\n  return headerLen <= 1024 * 1024 && 12 + headerLen <= buf.length - 32;\n}","typeGuard":"function isPlausibleRvfa(buf: Buffer): buf is Buffer {\n  return buf.length >= 44 && 12 + buf.readUInt32LE(8) <= buf.length - 32;\n}","tryCatchPattern":"try {\n  const reader = RvfaReader.fromBuffer(buf);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Buffer too small to contain declared header') {\n    // file truncated: re-download, don't retry with the same bytes\n  }\n  throw e;\n}","preventionTips":["Always size-check downloads against the published image size before parsing","When building buffers, write headerLen from the exact byte length of the serialized JSON, not an estimate","End-to-end checksum artifacts so truncation is caught at transfer time, not parse time"],"tags":["rvfa","binary-format","truncated-file","buffer-bounds"],"backgroundTag":"truncated-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"}