ruvnet/ruflo · error · Error
KV cache file too small
Error message
KV cache file too small
What it means
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.
Source
Thrown at v3/@claude-flow/cli/src/appliance/gguf-engine.ts:389
entryBufs.push(hdr, keyBuf, value);
}
const entryData = Buffer.concat(entryBufs);
const footer = createHash('sha256').update(entryData).digest();
const header = Buffer.alloc(44);
header.writeUInt32LE(RVKV_MAGIC, 0);
header.writeUInt32LE(RVKV_VERSION, 4);
modelHash.copy(header, 8);
header.writeUInt32LE(this.kvCache.size, 40);
await writeFile(path, Buffer.concat([header, entryData, footer]));
if (this.config.verbose) console.log(`[gguf-engine] KV cache persisted: ${this.kvCache.size} entries`);
}
/** Restore KV cache from an RVF-compatible binary file. */
async loadKvCache(inputPath: string): Promise<void> {
const data = await readFile(inputPath);
if (data.length < 44) throw new Error('KV cache file too small');
const magic = data.readUInt32LE(0);
if (magic !== RVKV_MAGIC) throw new Error(`Invalid KV cache magic: 0x${magic.toString(16)}`);
const version = data.readUInt32LE(4);
if (version !== RVKV_VERSION) throw new Error(`Unsupported KV cache version: ${version}`);
const entryCount = data.readUInt32LE(40);
let offset = 44;
const entries = new Map<string, Buffer>();
for (let i = 0; i < entryCount; i++) {
if (offset + 8 > data.length) throw new Error('KV cache file truncated');
const keyLen = data.readUInt32LE(offset);
const valLen = data.readUInt32LE(offset + 4);
offset += 8;
if (offset + keyLen + valLen > data.length) throw new Error('KV cache file truncated');
entries.set(data.toString('utf-8', offset, offset + keyLen), Buffer.from(data.subarray(offset + keyLen, offset + keyLen + valLen)));
offset += keyLen + valLen;View on GitHub (pinned to 6b01dc5a68)
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.
Example fix
// before
await engine.loadKvCache(path);
// after
const stat = await fsStat(path);
if (stat.size < 44) {
logger.warn({ path, size: stat.size }, 'KV cache too small; starting cold');
await fsUnlink(path).catch(() => {});
} else {
await engine.loadKvCache(path);
} Defensive patterns
Strategy: validation
Validate before calling
const stat = await fsStat(path);
if (stat.size < 44) {
logger.warn({ path, size: stat.size }, 'KV cache below minimum header size');
await fsUnlink(path).catch(() => {});
return; // cold start
}
await engine.loadKvCache(path); Type guard
function meetsMinHeaderSize(size: number): boolean {
return size >= 44;
} Try / catch
try {
await engine.loadKvCache(path);
} catch (e) {
if (e instanceof Error && /file too small/.test(e.message)) {
await fsUnlink(path).catch(() => {});
return; // cold start
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid KV cache magic: 0x${magic.toString(16)}
- KV cache file truncated
- KV cache file missing SHA256 footer
- KV cache integrity check failed: hash mismatch
- String length ${len} exceeds remaining buffer
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/c2558ce168f737c5.
Report an issue: GitHub.