ruvnet/ruflo · error
ProductQuantizer must be trained before computing distances
Error message
ProductQuantizer must be trained before computing distances
What it means
Thrown by ProductQuantizer.computeDistances() (asymmetric distance computation, ADC) when isTrained is false. ADC builds per-subvector distance lookup tables from the learned codebook centroids; without training the codebooks do not exist and distances cannot be computed. The guard prevents meaningless NaN results.
Source
Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts:939
dequantize(quantized: Uint8Array[]): number[][] {
return this.decode(quantized);
}
/**
* Computes asymmetric distances from a query to encoded vectors.
*
* Asymmetric distance computation (ADC):
* - Query is NOT quantized (exact)
* - Database vectors are quantized (codes)
* - Distance is computed using lookup tables
*
* @param query - Query vector (float)
* @param codes - Database PQ codes
* @returns Array of distances
*/
computeDistances(query: number[], codes: Uint8Array[]): number[] {
if (!this.isTrained) {
throw new Error('ProductQuantizer must be trained before computing distances');
}
// Build distance lookup tables
const distanceTables = this.buildDistanceTables(query);
// Compute distances using tables
return codes.map((code) => {
let distance = 0;
for (let m = 0; m < this.numSubvectors; m++) {
distance += distanceTables[m][code[m]];
}
return Math.sqrt(distance);
});
}
/**
* Builds distance lookup tables for asymmetric distance computation.
*/View on GitHub (pinned to fa13ee4ad6)
Solutions
- Train before searching: pq.train(trainingVectors) then computeDistances(query, codes)
- Load the persisted model: pq.setCodebooks(savedCodebooks) or deserializeQuantizer(blob) at service startup, then serve queries
- Check pq.trained at request time and fail fast with a clear 'quantizer not loaded' message before touching codes
Example fix
// before
const pq = new ProductQuantizer({ dimensions: 128, numSubvectors: 16 });
const dists = pq.computeDistances(query, dbCodes); // throws
// after
const pq = deserializeQuantizer(fs.readFileSync('pq-model.json', 'utf8'));
const dists = pq.computeDistances(query, dbCodes); Defensive patterns
Strategy: validation
Validate before calling
if (!pq.trained) {
throw new Error('Search unavailable: quantizer model not loaded');
}
const dists = pq.computeDistances(query, dbCodes); Type guard
const isSearchReady = (q: ProductQuantizer): boolean => q.trained && q.trained;
Try / catch
try {
return pq.computeDistances(query, codes);
} catch (err) {
if (err instanceof Error && err.message.includes('must be trained')) {
// fail the request loudly; retraining inline is usually wrong in serving paths
throw new ServiceUnavailableError('vector index not warmed up');
}
throw err;
} Prevention
- Load pretrained codebooks during service bootstrap and assert pq.trained before accepting traffic
- Expose trained state in readiness probes so unwarmed replicas are skipped
- Keep one shared trained instance rather than constructing per request
When it happens
Trigger: Calling computeDistances(query, codes) on a quantizer that was never trained — e.g. a search-time instance built per-request from options only, or one whose codebooks failed to load from storage.
Common situations: Serving path constructs a new ProductQuantizer for each query and forgets to restore persisted codebooks; training happened in a batch job but the deployed service never loads the artifact; unit test exercises search without the training fixture.
Related errors
- ProductQuantizer must be trained before decoding
- Cannot calibrate with empty samples
- Cannot learn thresholds from empty samples
- Dimensions (${options.dimensions}) must be divisible by numS
- Need at least ${this.numCentroids} training vectors, got ${v
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/0fd06bbb8aaf1aa2.
Report an issue: GitHub.