ruvnet/ruflo · error

Cannot calibrate with empty samples

Error message

Cannot calibrate with empty samples

What it means

ScalarQuantizer.calibrate() (quantization.ts:331) derives minValue/maxValue by scanning sample vectors, so at least one sample is required; an empty array throws. Calibration is optional — the constructor already calibrates when minValue/maxValue are passed explicitly — and calibrate() marks the quantizer isCalibrated.

Source

Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts:331

      maxValue: options.maxValue ?? 1,
      scale: 1,
      zeroPoint: 0,
    };

    if (options.minValue !== undefined && options.maxValue !== undefined) {
      this.computeCalibration(options.minValue, options.maxValue);
      this.isCalibrated = true;
    }
  }

  /**
   * Calibrates the quantizer using sample vectors.
   *
   * @param samples - Representative vectors for calibration
   */
  calibrate(samples: number[][]): void {
    if (samples.length === 0) {
      throw new Error('Cannot calibrate with empty samples');
    }

    // Find min and max across all dimensions and samples
    let minValue = Infinity;
    let maxValue = -Infinity;

    for (const sample of samples) {
      for (let i = 0; i < sample.length; i++) {
        minValue = Math.min(minValue, sample[i]);
        maxValue = Math.max(maxValue, sample[i]);
      }
    }

    // Add small margin for numerical stability
    const range = maxValue - minValue;
    minValue -= range * 0.01;
    maxValue += range * 0.01;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Skip or defer calibration when samples.length === 0
  2. Pass explicit minValue/maxValue to the constructor instead of calibrating (e.g. -1/1 for normalized embeddings)
  3. Log the sample count before calibrating so empty inputs are visible in ops

Example fix

// before
quantizer.calibrate(await sampleEmbeddings()); // throws on empty table

// after
const samples = await sampleEmbeddings();
if (samples.length > 0) {
  quantizer.calibrate(samples);
} else {
  logger.warn('Skipping calibration: no samples yet');
}
Defensive patterns

Strategy: validation

Validate before calling

if (samples.length === 0) {
  throw new Error(`Calibration requires samples, got 0 (source: ${source})`);
}
quantizer.calibrate(samples);

Type guard

function isNonEmptySamples(v: number[][]): v is [number[], ...number[][]] {
  return Array.isArray(v) && v.length > 0;
}

Try / catch

try {
  quantizer.calibrate(samples);
} catch (err) {
  if (err instanceof Error && err.message === 'Cannot calibrate with empty samples') {
    // keep constructor defaults (minValue/maxValue) and retry once data arrives
    logger.warn('Calibration skipped: no samples');
  } else throw err;
}

Prevention

When it happens

Trigger: quantizer.calibrate([]) after a sampling step filtered out all rows (e.g. empty table, WHERE clause matching nothing, warmup before data lands); passing a training split that is empty due to a shuffling bug.

Common situations: New deployments pointing at an empty database; calibration jobs racing data ingestion; filters on embedding metadata removing every candidate.

Related errors


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