{"record":{"id":"a0b9eeff23a6ff20","repo":"ruvnet/ruflo","slug":"kv-cache-file-truncated","errorCode":null,"errorMessage":"KV cache file truncated","messagePattern":"KV cache file truncated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/gguf-engine.ts","lineNumber":401,"sourceCode":"    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;\n    }\n\n    // Verify footer hash (mandatory)\n    if (offset + 32 > data.length) {\n      throw new Error('KV cache file missing SHA256 footer');\n    }\n    const stored = data.subarray(offset, offset + 32);\n    const computed = createHash('sha256').update(data.subarray(44, offset)).digest();\n    if (!stored.equals(computed)) throw new Error('KV cache integrity check failed: hash mismatch');\n\n    this.kvCache = entries;\n    if (this.config.verbose) console.log(`[gguf-engine] KV cache loaded: ${entries.size} entries`);","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/gguf-engine.ts#L383-L419","documentation":"While walking the entry list (count from the header), loadKvCache throws as soon as an entry header (8 bytes) or an entry body (keyLen+valLen bytes) would read past the end of the file. The declared entries exceed the bytes actually present — an interrupted write, a partial copy, or disk-full during persistKvCache.","triggerScenarios":"Process crash or kill during persistKvCache's single writeFile; copying the cache file while it is still being written; disk quota hit mid-write; a corrupted entry-count field.","commonSituations":"Hard-killed appliance processes; backup jobs copying live cache files; shared storage with quotas; non-atomic file management scripts.","solutions":["Regenerate the cache: delete the truncated file and re-run persistKvCache (optionally after a warm-up generate)","If you manage cache files yourself, copy/move them atomically (temp file + rename)","Catch this error and continue with a cold cache rather than aborting the session"],"exampleFix":"// before\nawait engine.loadKvCache(cachePath);\n\n// after\ntry {\n  await engine.loadKvCache(cachePath);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('truncated')) {\n    await rm(cachePath, { force: true });\n    await engine.persistKvCache(cachePath);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await engine.loadKvCache(cachePath); }\ncatch (e) {\n  if (e instanceof Error && e.message.includes('truncated')) {\n    await rm(cachePath, { force: true });\n    await engine.persistKvCache(cachePath);\n  } else throw e;\n}","preventionTips":["Copy/move cache files atomically (temp + rename); never copy a file being written","Ensure persistKvCache completes before shutdown (graceful drain)","Monitor disk space where caches live; quota exhaustion mid-write is a common cause"],"tags":["kv-cache","truncated-file","binary-parsing","nodejs"],"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"}