ruvnet/ruflo · error
Cannot learn thresholds from empty samples
Error message
Cannot learn thresholds from empty samples
What it means
BinaryQuantizer.learnThresholds() (quantization.ts:500) computes a per-dimension median threshold from training vectors to decide the 0/1 bit each dimension encodes. Median computation requires at least one value per dimension, so an empty samples array throws. The quantizer otherwise falls back to zero thresholds.
Source
Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts:500
private readonly bytesPerVector: number;
constructor(options: BinaryQuantizationOptions) {
this.dimensions = options.dimensions;
this.threshold = options.threshold ?? 0;
this.learnedThresholds = options.learnedThresholds ?? null;
// Calculate bytes needed (ceil(dimensions / 8))
this.bytesPerVector = Math.ceil(this.dimensions / 8);
}
/**
* Learns optimal thresholds per dimension from training data.
*
* @param samples - Training vectors
*/
learnThresholds(samples: number[][]): void {
if (samples.length === 0) {
throw new Error('Cannot learn thresholds from empty samples');
}
// Compute median per dimension as threshold
this.learnedThresholds = new Array(this.dimensions);
for (let d = 0; d < this.dimensions; d++) {
const values = samples.map(s => s[d]).sort((a, b) => a - b);
const mid = Math.floor(values.length / 2);
this.learnedThresholds[d] = values.length % 2 === 0
? (values[mid - 1] + values[mid]) / 2
: values[mid];
}
}
/**
* Quantizes float32 vectors to binary.
*
* @param vectors - Input vectorsView on GitHub (pinned to fa13ee4ad6)
Solutions
- Guard the call: only invoke learnThresholds when samples.length > 0
- Fall back to the default zero thresholds (skip learning) when data is missing
- Fail the job earlier with a clear message if training data is a hard requirement
Example fix
// before
bq.learnThresholds(trainSet); // throws if trainSet is []
// after
if (trainSet.length > 0) {
bq.learnThresholds(trainSet);
} else {
bq.learnThresholds([new Array(bq.dimensions).fill(0)]); // neutral threshold until data arrives
} Defensive patterns
Strategy: validation
Validate before calling
if (samples.length === 0) {
throw new Error('learnThresholds requires at least one training vector');
}
bq.learnThresholds(samples); Type guard
function isNonEmptySamples(v: number[][]): v is [number[], ...number[][]] {
return Array.isArray(v) && v.length > 0;
} Try / catch
try {
bq.learnThresholds(samples);
} catch (err) {
if (err instanceof Error && err.message === 'Cannot learn thresholds from empty samples') {
bq.learnThresholds([new Array(dim).fill(0)]); // neutral thresholds until real data
} else throw err;
} Prevention
- Validate training-set size before threshold learning
- Make empty ETL results loud (log/abort) instead of flowing into quantizer training
- Include non-empty vector fixtures in unit tests for the binary quantizer
When it happens
Trigger: learnThresholds([]) when the training fetch returned no rows; slicing a dataset with .slice(0, 0) or an empty feature group; test fixtures that forgot to include vectors.
Common situations: First-run pipelines before any data exists; ETL filters (tenant, date range) producing empty result sets; unit tests with stubbed empty datasets.
Related errors
- Cannot calibrate with empty samples
- Need at least ${this.numCentroids} training vectors, got ${v
- Invalid --worker spec "${spec}". Missing prompt after "<plat
- Cannot compute centroid of empty set
- Dimensions (${options.dimensions}) must be divisible by numS
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/19322f319085db44.
Report an issue: GitHub.