ruvnet/ruflo · error · Error

No KV cache output path specified

Error message

No KV cache output path specified

What it means

Thrown by persistKvCache when both the outputPath argument and this.config.kvCachePath are falsy. The persistence format (RVKV magic | version | model SHA-256 | entries | footer SHA-256) requires a destination file; with no path there is nowhere to write.

Source

Thrown at v3/@claude-flow/cli/src/appliance/gguf-engine.ts:362

            if (typeof chunk === 'string') yield chunk;
            else if (chunk?.text) yield chunk.text;
          }
          return;
        }
      } catch { /* fall through to single-chunk fallback */ }
    }
    const response = await this.generate(request);
    yield response.text;
  }

  /**
   * Persist the KV cache to an RVF-compatible binary file.
   * Format: RVKV magic | version u32 | model SHA-256 (32B) | entry count u32
   *         entries: [key_len u32, key, val_len u32, val] | footer SHA-256 (32B)
   */
  async persistKvCache(outputPath: string): Promise<void> {
    const path = outputPath || this.config.kvCachePath;
    if (!path) throw new Error('No KV cache output path specified');

    const modelHash = createHash('sha256').update(this.activeModelPath ?? 'no-model').digest();
    const entryBufs: Buffer[] = [];
    for (const [key, value] of this.kvCache) {
      const keyBuf = Buffer.from(key, 'utf-8');
      const hdr = Buffer.alloc(8);
      hdr.writeUInt32LE(keyBuf.length, 0);
      hdr.writeUInt32LE(value.length, 4);
      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);

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Pass an explicit output path: await persistKvCache('/var/ruv/kvcache.rvkv').
  2. Set config.kvCachePath at construction time so persistKvCache() has a default.
  3. Validate the path is a non-empty string before calling, and ensure the parent directory exists and is writable.
  4. If persistence is optional in your flow, guard the call behind a check that a path was configured.

Example fix

// before
await engine.persistKvCache();

// after
const out = outputPath ?? config.kvCachePath;
if (!out) throw new Error('configure kvCachePath or pass an output path');
await fs.mkdir(dirname(out), { recursive: true });
await engine.persistKvCache(out);
Defensive patterns

Strategy: validation

Validate before calling

const out = outputPath ?? config.kvCachePath;
if (!out || typeof out !== 'string') {
  throw new Error('configure kvCachePath or pass an output path to persistKvCache');
}
await engine.persistKvCache(out);

Type guard

function hasKvCachePath(p: string | undefined | null): p is string {
  return typeof p === 'string' && p.length > 0;
}

Try / catch

try {
  await engine.persistKvCache(outputPath);
} catch (e) {
  if (e instanceof Error && /No KV cache output path/.test(e.message)) {
    throw new Error('must configure kvCachePath');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling persistKvCache() (no argument) on a bridge/engine whose config never set kvCachePath, or calling persistKvCache('') with an empty string. The fallback `outputPath || this.config.kvCachePath` resolves to undefined/empty.

Common situations: Default config object omits kvCachePath (it is optional); a caller that constructs the bridge for inference only and later tries to snapshot the KV cache without specifying where; programmatic use that passes undefined instead of a concrete path.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/5f8ec3d6591ed24b. Report an issue: GitHub.