{"record":{"id":"c2558ce168f737c5","repo":"ruvnet/ruflo","slug":"kv-cache-file-too-small","errorCode":null,"errorMessage":"KV cache file too small","messagePattern":"KV cache file too small","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/gguf-engine.ts","lineNumber":389,"sourceCode":"      entryBufs.push(hdr, keyBuf, value);\n    }\n    const entryData = Buffer.concat(entryBufs);\n    const footer = createHash('sha256').update(entryData).digest();\n\n    const header = Buffer.alloc(44);\n    header.writeUInt32LE(RVKV_MAGIC, 0);\n    header.writeUInt32LE(RVKV_VERSION, 4);\n    modelHash.copy(header, 8);\n    header.writeUInt32LE(this.kvCache.size, 40);\n\n    await writeFile(path, Buffer.concat([header, entryData, footer]));\n    if (this.config.verbose) console.log(`[gguf-engine] KV cache persisted: ${this.kvCache.size} entries`);\n  }\n\n  /** Restore KV cache from an RVF-compatible binary file. */\n  async loadKvCache(inputPath: string): Promise<void> {\n    const data = await readFile(inputPath);\n    if (data.length < 44) throw new Error('KV cache file too small');\n\n    const magic = data.readUInt32LE(0);\n    if (magic !== RVKV_MAGIC) throw new Error(`Invalid KV cache magic: 0x${magic.toString(16)}`);\n    const version = data.readUInt32LE(4);\n    if (version !== RVKV_VERSION) throw new Error(`Unsupported KV cache version: ${version}`);\n\n    const entryCount = data.readUInt32LE(40);\n    let offset = 44;\n    const entries = new Map<string, Buffer>();\n\n    for (let i = 0; i < entryCount; i++) {\n      if (offset + 8 > data.length) throw new Error('KV cache file truncated');\n      const keyLen = data.readUInt32LE(offset);\n      const valLen = data.readUInt32LE(offset + 4);\n      offset += 8;\n      if (offset + keyLen + valLen > data.length) throw new Error('KV cache file truncated');\n      entries.set(data.toString('utf-8', offset, offset + keyLen), Buffer.from(data.subarray(offset + keyLen, offset + keyLen + valLen)));\n      offset += keyLen + valLen;","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/appliance/gguf-engine.ts#L371-L407","documentation":"Thrown by loadKvCache when the loaded file is shorter than 44 bytes. The RVKV format header alone is 44 bytes (4 magic + 4 version + 32 model hash + 4 entry count), so anything smaller cannot even contain a valid header. This is the first integrity gate on cache files.","triggerScenarios":"Loading an empty file, a near-empty file, or a path that points to a different/tiny artifact. readFileSync succeeds (no ENOENT) but the buffer is below the minimum header size.","commonSituations":"An interrupted persistKvCache left a zero-byte file behind; pointing loadKvCache at a placeholder/pid file or a totally different format; the cache path was never written to because persistKvCache failed earlier.","solutions":["Check the file size and mtime before loading; if it is < 44 bytes or zero bytes, delete it and regenerate via persistKvCache.","Ensure persistKvCache completed successfully in a prior run (look for the success log line and a non-trivial file size).","Confirm loadKvCache is pointed at a file previously produced by persistKvCache of the same engine, not an arbitrary path.","Wrap loadKvCache so a missing/corrupt cache falls back to a cold start instead of crashing."],"exampleFix":"// before\nawait engine.loadKvCache(path);\n\n// after\nconst stat = await fsStat(path);\nif (stat.size < 44) {\n  logger.warn({ path, size: stat.size }, 'KV cache too small; starting cold');\n  await fsUnlink(path).catch(() => {});\n} else {\n  await engine.loadKvCache(path);\n}","handlingStrategy":"validation","validationCode":"const stat = await fsStat(path);\nif (stat.size < 44) {\n  logger.warn({ path, size: stat.size }, 'KV cache below minimum header size');\n  await fsUnlink(path).catch(() => {});\n  return; // cold start\n}\nawait engine.loadKvCache(path);","typeGuard":"function meetsMinHeaderSize(size: number): boolean {\n  return size >= 44;\n}","tryCatchPattern":"try {\n  await engine.loadKvCache(path);\n} catch (e) {\n  if (e instanceof Error && /file too small/.test(e.message)) {\n    await fsUnlink(path).catch(() => {});\n    return; // cold start\n  }\n  throw e;\n}","preventionTips":["Check file size before loading; purge tiny/empty files.","Ensure persistKvCache completed before relying on the cache.","Atomic-write caches so partial files never exist.","Fall back to a cold cache on size failure."],"tags":["gguf","kv-cache","integrity","file-format"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}