{"record":{"id":"4e3f98a110f03b73","repo":"ruvnet/ruflo","slug":"embedding-must-be-float32array-of-length-this-di","errorCode":null,"errorMessage":"Embedding must be Float32Array of length ${this.dimension}","messagePattern":"Embedding must be Float32Array of length (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/ruvector/semantic-router.ts","lineNumber":62,"sourceCode":"    this.metric = config.metric ?? 'cosine';\n  }\n\n  /**\n   * Add an intent with pre-computed embeddings\n   */\n  addIntentWithEmbeddings(\n    name: string,\n    embeddings: Float32Array[],\n    metadata: Record<string, unknown> = {}\n  ): void {\n    if (!name || !Array.isArray(embeddings)) {\n      throw new Error('Must provide name and embeddings array');\n    }\n\n    // Validate embeddings\n    for (const emb of embeddings) {\n      if (!(emb instanceof Float32Array) || emb.length !== this.dimension) {\n        throw new Error(`Embedding must be Float32Array of length ${this.dimension}`);\n      }\n    }\n\n    // Normalize embeddings for cosine similarity\n    const normalizedEmbeddings = embeddings.map(emb => this.normalize(emb));\n\n    this.intents.set(name, {\n      name,\n      embeddings: normalizedEmbeddings,\n      metadata,\n    });\n    this.totalVectors += embeddings.length;\n  }\n\n  /**\n   * Route a query using a pre-computed embedding\n   */\n  routeWithEmbedding(embedding: Float32Array, k = 5): RouteResult[] {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/ruvector/semantic-router.ts#L44-L80","documentation":"Thrown by SemanticRouter.addIntentWithEmbeddings when any element of the embeddings array is not a Float32Array instance or its length differs from the dimension configured in the RouterConfig passed to the constructor. The router compares intent and query vectors component-by-component for cosine similarity, so wrong-type or wrong-length vectors are rejected up front instead of producing meaningless scores. Note the check is instanceof-based: a plain number[] (e.g. after JSON round-trip) fails even if the length is correct.","triggerScenarios":"Calling router.addIntentWithEmbeddings(name, embeddings) where embeddings came from JSON.parse (plain Array), where vectors were produced by a different embedding model whose output dimension differs from config.dimension, or where one element of the array is empty/truncated.","commonSituations":"Persisting intent embeddings to disk as JSON and reloading them (Float32Array serializes to a normal array), swapping embedding providers (e.g. 1536-dim OpenAI text-embedding vs 384-dim MiniLM) without updating the router's dimension, mixing example vectors from an old training run with a new router config.","solutions":["Rehydrate every vector before registering: embeddings.map(v => v instanceof Float32Array ? v : Float32Array.from(v))","Confirm each vector's length equals the dimension in your RouterConfig; regenerate embeddings if the embedding model changed","If you genuinely have mixed dimensions, use one SemanticRouter instance per dimension instead of one router for all"],"exampleFix":"// before\nconst saved = JSON.parse(fs.readFileSync('intents.json', 'utf8'));\nrouter.addIntentWithEmbeddings('greet', saved.embeddings); // plain arrays -> throws\n\n// after\nconst saved = JSON.parse(fs.readFileSync('intents.json', 'utf8'));\nconst vecs = saved.embeddings.map((v: number[]) => Float32Array.from(v));\n// assert lengths match the configured dimension\nif (!vecs.every(v => v.length === routerDim)) throw new Error('stale embeddings; regenerate');\nrouter.addIntentWithEmbeddings('greet', vecs);","handlingStrategy":"type-guard","validationCode":"const DIM = 384; // must equal RouterConfig.dimension\nconst valid = intentEmbeddings.every(e => e instanceof Float32Array && e.length === DIM);\nif (!valid) intentEmbeddings = intentEmbeddings.map(e => Float32Array.from(e as number[]));\nif (!intentEmbeddings.every(e => e.length === DIM)) throw new TypeError('embeddings have wrong dimension — regenerate with the current model');","typeGuard":"function isTrainedEmbedding(v: unknown, dim: number): v is Float32Array {\n  return v instanceof Float32Array && v.length === dim;\n}","tryCatchPattern":null,"preventionTips":["Derive RouterConfig.dimension from the embedding model's declared output size, never a hardcoded literal in two places","Always rehydrate persisted embeddings with Float32Array.from() after JSON/disk round-trips","Add a startup assertion that every intent embedding length matches the configured dimension"],"tags":["semantic-router","embeddings","float32array","validation","ruvector"],"backgroundTag":"embedding-dimension-mismatch","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}