ruvnet/ruflo · error

Expected ${this.dimensions}x${this.dimensions} matrix

Error message

Expected ${this.dimensions}x${this.dimensions} matrix

What it means

Thrown by OptimizedProductQuantizer.setRotationMatrix() when the supplied matrix is not exactly dimensions x dimensions. The rotation (Hadamard-like) matrix must be square and match the vector dimensionality because encoding applies it to full input vectors. A wrong-shape matrix means the loaded OPQ state does not correspond to this quantizer's configuration.

Source

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

    const rotatedQuery = this.rotationMatrix
      ? matVec(this.rotationMatrix, query)
      : query;
    return super.computeDistances(rotatedQuery, codes);
  }

  /**
   * Gets the rotation matrix.
   */
  getRotationMatrix(): number[][] | null {
    return this.rotationMatrix ? this.rotationMatrix.map(r => [...r]) : null;
  }

  /**
   * Sets the rotation matrix directly.
   */
  setRotationMatrix(matrix: number[][]): void {
    if (matrix.length !== this.dimensions || matrix[0].length !== this.dimensions) {
      throw new Error(`Expected ${this.dimensions}x${this.dimensions} matrix`);
    }
    this.rotationMatrix = matrix.map(r => [...r]);
  }
}

// ============================================================================
// SQL Integration
// ============================================================================

/**
 * QuantizationSQL generates SQL for quantized vector operations.
 *
 * Provides SQL statements for:
 * - Creating quantized storage tables
 * - Inserting quantized vectors
 * - Searching with quantized distances
 */
export class QuantizationSQL {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Retrain OPQ with the current dimensions and persist the new rotation matrix together with the codebooks
  2. Load artifacts only into an OptimizedProductQuantizer constructed with the dimensions the artifact was trained for (store dimensions in the artifact metadata)
  3. Validate matrix.length and every matrix[i].length === dimensions before calling setRotationMatrix

Example fix

// before
const opq = new OptimizedProductQuantizer({ dimensions: 768, /* ... */ });
opq.setRotationMatrix(savedFrom384Model.rotationMatrix); // throws

// after
const opq = new OptimizedProductQuantizer({ dimensions: saved.dimensions, /* ... */ });
opq.setRotationMatrix(saved.rotationMatrix);
Defensive patterns

Strategy: validation

Validate before calling

const isSquare =
  matrix.length === dims && matrix.every(row => row.length === dims);
if (!isSquare) {
  throw new Error(`Rotation matrix must be ${dims}x${dims}`);
}
opq.setRotationMatrix(matrix);

Type guard

const isRotationMatrix = (m: unknown, dims: number): m is number[][] =>
  Array.isArray(m) &&
  m.length === dims &&
  (m as number[][]).every(r => Array.isArray(r) && r.length === dims &&
    r.every(Number.isFinite));

Try / catch

try {
  opq.setRotationMatrix(matrix);
} catch (err) {
  if (err instanceof Error && err.message.includes('x')) { // shape message
    throw new Error(`OPQ artifact dimension mismatch: ${err.message} — retrain for dims=${opq.dimensions}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Loading a rotation matrix trained for a different embedding dimension (e.g. 384 vs 768) into the current quantizer; passing a transposed or ragged (uneven row lengths) matrix; hand-editing serialized JSON and dropping a row.

Common situations: Switching embedding models without retraining the OPQ space; artifacts from a staging dimension reused in production; JSON round-trips that silently truncate rows.

Related errors


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