ruvnet/ruflo · error · Error

tuneDistillation: every grid candidate was skipped — see can

Error message

tuneDistillation: every grid candidate was skipped — see candidates[].skipped

What it means

After evaluating every grid config, tuneDistillation filters out candidates whose result.skipped is set; if all of them were skipped, none remain to select a winner and the harness throws, telling the caller to inspect candidates[].skipped for per-config skip reasons.

Source

Thrown at v3/@claude-flow/cli/src/services/distill-tuning.ts:306

      namespaces,
      querySet: trainQuerySet,
      topK,
    });
    candidates.push({
      config,
      trainScore: result.mrrAtK,
      trainRecallAt10: result.recallAtK,
      trainQueryCount: result.queryCount,
      patternCount: result.patternCount,
      promotedCount: result.promotedCount,
      distillMs: result.distillMs,
      ...(result.skipped ? { skipped: result.skipped } : {}),
    });
  }

  const scored = candidates.filter((c) => !c.skipped);
  if (scored.length === 0) {
    throw new Error('tuneDistillation: every grid candidate was skipped — see candidates[].skipped');
  }
  const winner = scored.reduce((best, c) => (c.trainScore > best.trainScore ? c : best), scored[0]);

  // ── Held-out: score the winner ONCE, refit on the FULL outer train partition ──
  const winnerFull = await evaluateCandidate({
    Database,
    sourceDbPath: dbPath,
    tmpDir,
    config: winner.config,
    fitBoundaryRowid: outerSplit.trainBoundaryRowid,
    namespaces,
    querySet: heldOutQuerySet,
    topK,
  });
  const baseline = scoreQuerySet(heldOutBaselineIndex, heldOutQuerySet, topK);

  const heldOut: HeldOutScore = {
    mrrAt10: winnerFull.mrrAtK,

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Inspect the returned/caught candidates[].skipped reasons to find the common skip cause.
  2. Widen the grid (smaller dedupDistance, more permissive promoteThreshold) so at least one config survives.
  3. Ensure the db has enough rows in the chosen namespaces for a non-trivial train/held-out split.
  4. Relax the namespaces filter or pass namespaces: undefined to use defaults.

Example fix

// before
const result = await tuneDistillation({ dbPath, grid: { dedupDistance: [0.9] } }); // all skipped

// after — catch and inspect, then widen
try {
  const result = await tuneDistillation({ dbPath, grid });
} catch (e) {
  // re-run with a wider grid that lets at least one candidate through
  await tuneDistillation({ dbPath, grid: { dedupDistance: [0.05, 0.1, 0.2] } });
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot fully pre-validate; the skips are determined at eval time.
// Ensure the db has rows and the grid is non-degenerate before calling:
const rowCount = countRows(db, namespaces);
if (rowCount < minRowsForSplit) {
  throw new Error(`db has only ${rowCount} rows; widen namespaces or grow memory first`);
}

Try / catch

let result;
try {
  result = await tuneDistillation({ dbPath, grid });
} catch (e) {
  if ((e as Error).message.includes('every grid candidate was skipped')) {
    // widen the grid and retry once
    result = await tuneDistillation({ dbPath, grid: { dedupDistance: [0.05, 0.1, 0.2] } });
  } else throw e;
}

Prevention

When it happens

Trigger: Every config in the grid was skipped during evaluateCandidate — e.g. dedupDistance too aggressive leaving zero patterns, promoteThreshold excluding everything, batch sizes that error the distill step, or namespaces filters matching no rows.

Common situations: A db too small for the requested split (no training rows past the boundary); namespaces option narrowed to namespaces with no entries; grid values pushed to degenerate extremes; promoteThreshold ranges that admit nothing.

Related errors


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