{"record":{"id":"c8a03f032945d50d","repo":"ruvnet/ruflo","slug":"invalid-rvfa-magic-expected-rvfa-got-magic-c8a03f","errorCode":null,"errorMessage":"Invalid RVFA magic: expected \"RVFA\", got \"${magic}\"","messagePattern":"Invalid RVFA magic: expected \"RVFA\", got \"(.+?)\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-signing.ts","lineNumber":175,"sourceCode":"\n/**\n * Parse an RVFA binary into its components without full validation.\n * Returns the header object, header JSON bytes, section data region, and footer.\n */\nfunction parseRvfaBinary(buf: Buffer): {\n  header: Record<string, unknown>;\n  headerStart: number;\n  headerEnd: number;\n  sectionData: Buffer;\n  footer: Buffer;\n} {\n  if (buf.length < PREAMBLE_SIZE + SHA256_SIZE) {\n    throw new Error('Buffer too small to be a valid RVFA file');\n  }\n\n  const magic = buf.subarray(0, 4).toString('ascii');\n  if (magic !== 'RVFA') {\n    throw new Error(`Invalid RVFA magic: expected \"RVFA\", got \"${magic}\"`);\n  }\n\n  const headerLen = buf.readUInt32LE(8);\n  const headerStart = PREAMBLE_SIZE;\n  const headerEnd = headerStart + headerLen;\n\n  if (headerEnd > buf.length - SHA256_SIZE) {\n    throw new Error('Header length extends beyond buffer');\n  }\n\n  const headerJson = buf.subarray(headerStart, headerEnd).toString('utf-8');\n  let header: Record<string, unknown>;\n  try {\n    header = JSON.parse(headerJson) as Record<string, unknown>;\n  } catch {\n    throw new Error('Failed to parse RVFA header JSON');\n  }\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-signing.ts#L157-L193","documentation":"parseRvfaBinary found that the first 4 bytes are not the ASCII string 'RVFA'. The magic number is the format's first-line identity check — a wrong magic means the bytes are a different format entirely (or shifted by a prefix). The message helpfully echoes the bytes it saw, which is your main diagnostic.","triggerScenarios":"Feeding a non-RVFA file to the signing APIs: a tarball/zip/gzip artifact renamed to .rvfa, a Docker/OCI layer blob, or an RVFA image wrapped in an extra envelope so the magic sits past offset 0. The echoed magic in the message (e.g. 'PK\\u0003\\u0004' for zip, '\\u001f\\u008b' gzip) identifies the real format.","commonSituations":"Artifact-type confusion in CI (verify step pointed at the wrong artifact); images double-compressed (gzip'd RVFA); concatenation wrappers or signature-prepended formats shifting the payload; typos in file paths picking up a sibling file of another type.","solutions":["Read the echoed magic in the message and identify the actual format ('PK' = zip, '\\u001f\\u008b' = gzip, 'ustar' = tar) then unwrap/point at the real RVFA file","If the image is gzip-wrapped, gunzip it first — RVFA sections use internal gzip but the outer file must start with the magic","Check the path/config feeding the signing step — it's usually pointed at the wrong artifact","Regenerate the artifact with RvfaWriter if the original was never RVFA to begin with"],"exampleFix":"// before — verifying a still-compressed download\nconst buf = await readFile('appliance.rvfa.gz');\nawait verifier.verifyFile(buf, pub);\n\n// after — decompress the transport layer first\nconst buf = gunzipSync(await readFile('appliance.rvfa.gz'));\nawait verifier.verifyFile(buf, pub);","handlingStrategy":"validation","validationCode":"function looksLikeRvfa(buf: Buffer): boolean {\n  return buf.length >= 4 && buf.subarray(0, 4).toString('ascii') === 'RVFA';\n}\n// for gzipped transports: gunzipSync(buf) first, then check","typeGuard":"function isRvfaBuffer(buf: Buffer): buf is Buffer {\n  return buf.subarray(0, 4).toString('ascii') === 'RVFA';\n}","tryCatchPattern":"try { await verifyFile(buf, pub); }\ncatch (e) {\n  if (/Invalid RVFA magic/.test(String((e as Error).message))) {\n    // message echoes the bytes: 'PK'=zip, 0x1f8b=gzip -> unwrap and retry with the real payload\n  }\n  throw e;\n}","preventionTips":["Pin artifact paths explicitly in CI; never glob for '*.rvfa' next to other artifacts","Unwrap transport compression (gzip) before verification — magic must sit at offset 0","Use the echoed magic from the message to identify what you actually loaded"],"tags":["rvfa","signing","magic-bytes","file-format"],"backgroundTag":"invalid-magic-bytes","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"}