ruvnet/ruflo · error · Error
failed to load unified KRR
Error message
failed to load unified KRR
What it means
Thrown during router initialization when loadKrr(cfg.bundledKrrPath) returns null for the unified KRR artifact. loadKrr returns null if the file doesn't exist (existsSync false) or if JSON.parse / TrainedRouter.fromJSON throws inside its try/catch. The unified KRR is the router's primary model, so its absence means the MetaHarness-KRR path can't engage — the catch around the whole block then falls through to the k-NN seed-corpus fallback.
Source
Thrown at v3/@claude-flow/cli/src/ruvector/neural-router.ts:457
if (!existsSync(path)) return null;
try {
const json = JSON.parse(readFileSync(path, 'utf8'));
const trained = mh.TrainedRouter.fromJSON(json);
const cands = json.candidates.map((c: { id: string; costPerMTok: number }) => ({ id: c.id, costPerMTok: c.costPerMTok }));
return {
route: (e: number[]) => {
const r = trained.route(e);
return { id: r.id, predictedQuality: r.predictedQuality, costPerMTok: r.costPerMTok, metBar: r.metBar };
},
predictAll: (e: number[]) => cands.map((c: { id: string; costPerMTok: number }) => ({
id: c.id, predictedQuality: trained.predict(c.id, e), costPerMTok: c.costPerMTok,
})).sort((a: { costPerMTok: number }, b: { costPerMTok: number }) => a.costPerMTok - b.costPerMTok),
};
} catch { return null; }
};
const unifiedRaw = loadKrr(cfg.bundledKrrPath);
if (!unifiedRaw) throw new Error('failed to load unified KRR');
const unified = wrapWithCalibrator(unifiedRaw, unifiedCalibrator);
// ADR-149 iter 16 — load per-bucket specialists if present. Each is a
// KRR fit only to its tier's rows (cheap → low.json, mid → med.json,
// strong → high.json). When tryCostOptimalRoute is called with a
// complexityBucket, the matching specialist is preferred over the
// unified router.
const bucketDir = cfg.bundledKrrPath.replace(/seed-router\.krr\.json$/, '');
const routerByBucket: Partial<Record<'low' | 'med' | 'high', PureRouter>> = {};
const loadedBuckets: string[] = [];
for (const bucket of ['low', 'med', 'high'] as const) {
const r = loadKrr(`${bucketDir}seed-router.krr.${bucket}.json`);
if (r) {
// iter 25 — prefer tier-specific calibrator for this bucket;
// fall back to the unified calibrator when no specialist exists.
routerByBucket[bucket] = wrapWithCalibrator(r, calibratorByBucket[bucket] ?? unifiedCalibrator);
loadedBuckets.push(bucket);
}View on GitHub (pinned to 6b01dc5a68)
Solutions
- Check that cfg.bundledKrrPath exists with fs.existsSync and is valid JSON with JSON.parse before router init.
- Reinstall or rebuild the package so the bundled seed-router.krr.json is present and matches the runtime version.
- Set CLAUDE_FLOW_ROUTER_CALIBRATE=0 to rule out calibrator side-effects, and confirm the KRR specifically is the failing artifact.
- If the KRR can't be loaded, let the router fall through to the k-NN seed corpus (the code is designed to) — but verify the seed corpus path too.
Example fix
// before — assumes the bundled KRR loads
const router = await loadRouter(cfg);
// after — preflight the artifact and degrade gracefully
if (!existsSync(cfg.bundledKrrPath)) {
console.warn(`KRR missing at ${cfg.bundledKrrPath}; router will use k-NN fallback`);
} else {
try { JSON.parse(readFileSync(cfg.bundledKrrPath, 'utf8')); }
catch { console.warn('KRR artifact is malformed JSON; falling back'); }
}
const router = await loadRouter(cfg); Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, readFileSync } from 'node:fs';
function preflightKrr(path: string): { ok: true } | { ok: false; reason: string } {
if (!existsSync(path)) return { ok: false, reason: `KRR file missing at ${path}` };
try {
const j = JSON.parse(readFileSync(path, 'utf8'));
if (!j || !j.candidates) return { ok: false, reason: 'KRR JSON missing candidates[]' };
return { ok: true };
} catch (e) {
return { ok: false, reason: `KRR JSON parse failed: ${e}` };
}
}
const check = preflightKrr(cfg.bundledKrrPath);
if (!check.ok) console.warn(check.reason, '— router will fall through to k-NN'); Type guard
function isKrrLike(j: unknown): j is { candidates: unknown[] } {
return !!j && typeof j === 'object' && Array.isArray((j as any).candidates);
} Try / catch
try {
return await loadRouter(cfg); // throws 'failed to load unified KRR' inside
} catch (e) {
if (/failed to load unified KRR/.test(String(e))) {
// Code is designed to fall through to k-NN. Re-call with calibration disabled
// to isolate the cause, and surface the missing path to the operator.
console.error(`${e}. Expected at ${cfg.bundledKrrPath}. Falling back to k-NN.`);
return loadRouter({ ...cfg, calibrateEnabled: false });
}
throw e;
} Prevention
- Reinstall or rebuild the package so the bundled seed-router.krr.json matches the runtime version.
- Pre-flight the artifact (existsSync + JSON.parse + candidates[]) at startup so absence is a warning, not a crash.
- Keep CLAUDE_FLOW_ROUTER_CALIBRATE available to rule out calibrator interactions.
- If the KRR is genuinely unavailable, let the k-NN seed corpus take over — verify that path separately.
When it happens
Trigger: The bundled seed-router.krr.json artifact is missing from the package install (broken publish, gitignored file not shipped); the file exists but is malformed JSON; TrainedRouter.fromJSON rejects the schema (version mismatch with the MetaHarness library); the path cfg.bundledKrrPath points at the wrong location.
Common situations: Upgrading @claude-flow/cli across a version that changed the KRR file location/name; running from a source checkout without building the seed artifacts; the KRR was generated by a newer/older metaharness than the runtime expects; partial install where data/ artifacts weren't copied.
Related errors
- unsupported calibrator schema v=${j?.v}
- HTTP transport failed: ${String(firstError instanceof Error
- File too large: ${code.length} bytes exceeds ${this.config.m
- frozen human eval set not found (${FROZEN_HUMAN_EVAL_FILE})
- unsupported flywheel anchor schema: ${parsed.schemaVersion}
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/b88eb40342925642.
Report an issue: GitHub.