ruvnet/ruflo · error
Dimensions (${options.dimensions}) must be divisible by numS
Error message
Dimensions (${options.dimensions}) must be divisible by numSubvectors (${options.numSubvectors}) What it means
ProductQuantizer's constructor (quantization.ts:694) requires dimensions % numSubvectors === 0 because each subvector codebook covers an equal slice of dimensions (subvectorDim = dimensions / numSubvectors). Any remainder makes slicing ambiguous, so construction fails immediately with both values in the message.
Source
Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts:694
readonly dimensions: number;
readonly numSubvectors: number;
readonly numCentroids: number;
readonly subvectorDim: number;
protected codebooks: Codebook[] = [];
protected isTrained: boolean = false;
protected readonly maxIterations: number;
protected readonly tolerance: number;
protected readonly rng: () => number;
constructor(options: ProductQuantizationOptions) {
this.dimensions = options.dimensions;
this.numSubvectors = options.numSubvectors;
this.numCentroids = options.numCentroids;
// Validate dimensions divisibility
if (options.dimensions % options.numSubvectors !== 0) {
throw new Error(
`Dimensions (${options.dimensions}) must be divisible by numSubvectors (${options.numSubvectors})`
);
}
this.subvectorDim = options.dimensions / options.numSubvectors;
this.maxIterations = options.maxIterations ?? 100;
this.tolerance = options.tolerance ?? 1e-6;
this.rng = createRng(options.seed ?? 42);
}
/**
* Trains codebooks from training data using k-means clustering.
*
* @param vectors - Training vectors
*/
async train(vectors: number[][]): Promise<void> {
if (vectors.length < this.numCentroids) {
throw new Error(View on GitHub (pinned to fa13ee4ad6)
Solutions
- Pick numSubvectors that divides dimensions exactly (e.g. 1536: 8, 16, 24, 32, 48; 768: 8, 12, 16, 24)
- Compute it: const m = largestPowerOfTwoDividing(dimensions) or gcd-based choice
- Validate the pair in config loading: assert dimensions % numSubvectors === 0 with both values in the error
Example fix
// before
const pq = new ProductQuantizer({ dimensions: 1536, numSubvectors: 100, numCentroids: 256 }); // throws
// after
const dims = 1536;
const numSubvectors = 16; // 1536 / 16 = 96-dim subvectors
const pq = new ProductQuantizer({ dimensions: dims, numSubvectors, numCentroids: 256 }); Defensive patterns
Strategy: validation
Validate before calling
function assertPQOptions(dimensions: number, numSubvectors: number) {
if (!Number.isInteger(dimensions) || dimensions <= 0) throw new TypeError(`bad dimensions ${dimensions}`);
if (!Number.isInteger(numSubvectors) || numSubvectors <= 0) throw new TypeError(`bad numSubvectors ${numSubvectors}`);
if (dimensions % numSubvectors !== 0) {
throw new RangeError(`dimensions ${dimensions} not divisible by numSubvectors ${numSubvectors}`);
}
}
assertPQOptions(cfg.dimensions, cfg.numSubvectors);
const pq = new ProductQuantizer(cfg); Type guard
function isValidPQConfig(cfg: { dimensions: number; numSubvectors: number }): boolean {
return cfg.dimensions > 0 && cfg.numSubvectors > 0 && cfg.dimensions % cfg.numSubvectors === 0;
} Try / catch
try {
pq = new ProductQuantizer(cfg);
} catch (err) {
if (err instanceof Error && err.message.includes('must be divisible by numSubvectors')) {
cfg = { ...cfg, numSubvectors: 8 }; // retry with a standard divisor
pq = new ProductQuantizer(cfg);
} else throw err;
} Prevention
- Derive numSubvectors from the embedding model's dimension (1536 -> 16/24/48; 768 -> 8/12/16/24)
- Re-validate the pair whenever the embedding provider changes
- Encode the constraint in config schemas (multipleOf) so it fails at validation time
When it happens
Trigger: new ProductQuantizer({ dimensions: 1536, numSubvectors: 100 }) — 1536 % 100 != 0; reusing an 8-subvector config with a 312-dim embedding model; odd dimensions like 127 or 200 with non-divisor M.
Common situations: Switching embedding providers (1536 for ada-002, 768/1024 for others) without adjusting numSubvectors; copying the default M=8 into configs for models with dimensions not divisible by 8; hand-tuned M values that don't factor the dimension.
Related errors
- Need at least ${this.numCentroids} training vectors, got ${v
- ProductQuantizer must be trained before encoding
- Expected ${this.dimensions}x${this.dimensions} matrix
- Pool ${this.id} at maximum capacity (${this.config.maxWorker
- Invalid completion type
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/cff7603544ed2b2e.
Report an issue: GitHub.