ruvnet/ruflo · error

failed to load unified KRR

Error message

failed to load unified KRR

What it means

When building the routed engine, neural-router loads a trained-router artifact from cfg.bundledKrrPath (expected file seed-router.krr.json) via loadKrr(), which returns null when existsSync fails OR when reading/JSON.parse/TrainedRouter.fromJSON throws (all swallowed to null, neural-router.ts:438-454). A null unified artifact becomes this throw — the KRR (kernel routing rules) file is missing, unreadable, corrupt, or schema-incompatible.

Solutions

  1. Verify the artifact: check existsSync(cfg.bundledKrrPath) and dry-run JSON.parse on it in a REPL to surface the real cause
  2. Reinstall the package cleanly (rm -rf node_modules && npm install) so the bundled seed-router.krr.json is restored
  3. If bundledKrrPath was customized, point it at a known-good seed-router.krr.json matching your package version
  4. Fall back to the non-KRR routing path while regenerating or re-fetching the artifact

Example fix

// before
const router = tryCostOptimalRoute(...); // throws: failed to load unified KRR
// after (diagnose first)
import { existsSync, readFileSync } from 'node:fs';
const p = cfg.bundledKrrPath; // e.g. .../seed-router.krr.json
console.log('exists:', existsSync(p));
if (existsSync(p)) JSON.parse(readFileSync(p, 'utf8')); // surfaces parse/schema error
// then reinstall the package or fix bundledKrrPath before retrying
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync, readFileSync } from 'node:fs';
function krrIsLoadable(path: string): boolean {
  try { return existsSync(path) && !!JSON.parse(readFileSync(path, 'utf8')); }
  catch { return false; }
}

Type guard

function isLoadableKrrPath(path: string): boolean {
  if (!existsSync(path)) return false;
  try { JSON.parse(readFileSync(path, 'utf8')); return true; } catch { return false; }
}

Try / catch

try {
  router = buildRoutedEngine(cfg);
} catch (e) {
  if (e instanceof Error && e.message === 'failed to load unified KRR') {
    console.error(`KRR artifact missing/corrupt at ${cfg.bundledKrrPath} — using heuristic routing`);
    router = heuristicRouter; // degrade, then fix the artifact out-of-band
  } else throw e;
}

Prevention

When it happens

Trigger: Package installed without the bundled .krr.json asset (files excluded from the npm tarball); cfg.bundledKrrPath overridden to a wrong or moved location; truncated/corrupt file from a partial download; version skew where TrainedRouter.fromJSON rejects the JSON layout of a newer artifact.

Common situations: Fresh installs or CI caches with pruned optional assets; bundlers (esbuild/webpack) that fail to copy JSON sidecars into dist; upgrading @claude-flow/cli or the MetaHarness writer so the old seed-router.krr.json no longer parses; custom deployment paths that drop data files.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/b88eb40342925642. Report an issue: GitHub.

Appendix: 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 fa13ee4ad6)