{"record":{"id":"9c797f5729cbc5ad","repo":"ruvnet/ruflo","slug":"rvfa-header-failed-validation","errorCode":null,"errorMessage":"RVFA header failed validation","messagePattern":"RVFA header failed validation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-format.ts","lineNumber":350,"sourceCode":"      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;\n    for (const sec of header.sections) {\n      if (sec.offset < 0 || sec.size < 0) {\n        throw new Error(`Section \"${sec.id}\" has negative offset or size`);\n      }\n      if (sec.offset + sec.size > totalSize - SHA256_SIZE) {\n        throw new Error(\n          `Section \"${sec.id}\" extends beyond buffer ` +\n            `(offset=${sec.offset}, size=${sec.size}, bufLen=${totalSize})`,\n        );\n      }\n    }\n\n    // Check for overlapping sections","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-format.ts#L332-L368","documentation":"The header JSON parsed successfully but failed the exported validateHeader() type-guard (rvfa-format.ts:143-172). That check requires magic === 'RVFA', numeric version >= 1, string name/appVersion/arch/platform/created, profile in {cloud,hybrid,offline}, arrays for sections and capabilities, a well-formed boot object (entrypoint string, args array, env object, isolation enum), a models object with a valid provider, and — critically — every section entry having id/type/sha256 strings, numeric offset/size/originalSize, and compression in {none,gzip,zstd}. Structurally valid JSON that misses any of these is rejected.","triggerScenarios":"RvfaReader.fromBuffer on an image whose header omits a required field (e.g. no 'capabilities' array, boot.isolation misspelled as 'docker', or a section entry missing 'originalSize'). Also produced by third-party tools that emit a lookalike header with different field names or extra/missing keys.","commonSituations":"Hand-authored or machine-generated headers from external packaging scripts; schema drift between an old writer and a newer reader that added required fields; a header edited to change 'profile' or 'provider' to a value outside the allowed enums.","solutions":["Parse the header slice yourself (subarray(12, 12+readUInt32LE(8))) and run the exported validateHeader(parsed) — since it is a type-guard, iterate field-by-field to find which requirement fails","Regenerate the image with RvfaWriter/createDefaultHeader so all required fields and enum values are present","If the header was hand-edited, restore enum values to the allowed sets: profile cloud|hybrid|offline, boot.isolation container|microvm|native, models.provider ruvllm|api-vault|hybrid, section.compression none|gzip|zstd","Check every section entry has all six required keys: id, type, offset, size, originalSize, sha256, compression"],"exampleFix":"// before — unknown why validation failed\nconst reader = RvfaReader.fromBuffer(buf);\n\n// after — locate the failing field with the exported guard\nconst parsed = JSON.parse(buf.subarray(12, 12 + buf.readUInt32LE(8)).toString('utf8'));\nif (!validateHeader(parsed)) {\n  // check each requirement individually to pinpoint the missing/invalid field\n  console.error('bad fields:', Object.entries(parsed).filter(([k, v]) => v === undefined).map(([k]) => k));\n}","handlingStrategy":"validation","validationCode":"import { validateHeader } from './rvfa-format.js';\n\nconst parsed = JSON.parse(buf.subarray(12, 12 + buf.readUInt32LE(8)).toString('utf8'));\nif (!validateHeader(parsed)) {\n  throw new Error('header failed schema validation — regenerate image');\n}","typeGuard":"// the library exports the guard itself: validateHeader(header: unknown): header is RvfaHeader\nimport { validateHeader, type RvfaHeader } from './rvfa-format.js';\n\nfunction asRvfaHeader(v: unknown): RvfaHeader | null {\n  return validateHeader(v) ? v : null;\n}","tryCatchPattern":null,"preventionTips":["Build headers via createDefaultHeader(profile) so required fields are always present","Keep enum values within the allowed sets: profile, boot.isolation, models.provider, section.compression","When exporting headers for external tools, round-trip through validateHeader before writing"],"tags":["rvfa","schema-validation","type-guard","binary-format"],"backgroundTag":"schema-validation-failed","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"}