{"record":{"id":"43e182666297a5ca","repo":"ruvnet/ruflo","slug":"invalid-embedding-value-at-index-i-expected-fi","errorCode":null,"errorMessage":"Invalid embedding value at index ${i}: expected finite number, got ${typeof embedding[i]}","messagePattern":"Invalid embedding value at index (.+?): expected finite number, got (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/ruvector/import.ts","lineNumber":52,"sourceCode":" */\ninterface ImportStats {\n  total: number;\n  imported: number;\n  skipped: number;\n  errors: number;\n  withEmbeddings: number;\n  byNamespace: Record<string, number>;\n}\n\n/**\n * Format a ruvector embedding array for PostgreSQL\n * Validates each element is a finite number to prevent SQL injection via crafted arrays.\n */\nfunction formatEmbedding(embedding: number[], dimensions: number = 384): string {\n  // Validate every element is a finite number (prevents SQL injection via crafted JSON)\n  for (let i = 0; i < embedding.length; i++) {\n    if (typeof embedding[i] !== 'number' || !Number.isFinite(embedding[i])) {\n      throw new Error(`Invalid embedding value at index ${i}: expected finite number, got ${typeof embedding[i]}`);\n    }\n  }\n\n  // Ensure correct dimensions by padding or truncating\n  const padded = [...embedding];\n  while (padded.length < dimensions) {\n    padded.push(0);\n  }\n  if (padded.length > dimensions) {\n    padded.length = dimensions;\n  }\n  return `'[${padded.join(',')}]'::ruvector(${dimensions})`;\n}\n\n/**\n * Escape string for PostgreSQL\n */\nfunction escapeString(str: string): string {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/commands/ruvector/import.ts#L34-L70","documentation":"formatEmbedding() in the ruvector import command validates every element of each embedding array is a finite number before interpolating the array into a PostgreSQL vector literal '[...]'::ruvector(N). null, strings, NaN, or Infinity entries throw with the offending index — this is SQL-injection hardening for JSON-sourced data (CRIT class fix).","triggerScenarios":"Importing a JSON/JSONL dataset whose embedding arrays contain null (Python None), \"0.25\" as a string, or literal NaN/Infinity written by a non-strict serializer; also mixed-shape rows from truncated exports.","commonSituations":"Exporting embeddings from Python with missing values; json.dumps with allow_nan=True (default) emitting NaN; schema drift where the producer changed element types between runs.","solutions":["Preprocess the dataset: drop or impute non-numeric elements so every value is a finite number","In Python, re-export with json.dumps(data, allow_nan=False) and convert tensors via .tolist() on float32","Verify programmatically before import: rows.every(v => typeof v === 'number' && Number.isFinite(v))"],"exampleFix":"// before\n{\"id\":\"d1\",\"embedding\":[0.1,null,\"0.3\"]}\n\n// after\n{\"id\":\"d1\",\"embedding\":[0.1,0.0,0.3]}","handlingStrategy":"type-guard","validationCode":"for (const row of rows) {\n  if (!isFiniteVector(row.embedding)) {\n    row.embedding = row.embedding.map((v) => (typeof v === 'number' && Number.isFinite(v)) ? v : 0);\n  }\n}\n// only then run the import","typeGuard":"function isFiniteVector(v: unknown): v is number[] {\n  return Array.isArray(v) && v.every((x) => typeof x === 'number' && Number.isFinite(x));\n}","tryCatchPattern":"try {\n  await importRows(rows);\n} catch (err) {\n  if (err instanceof Error && /Invalid embedding value at index \\d+/.test(err.message)) {\n    // sanitize or drop the offending row, then retry the batch\n  } else throw err;\n}","preventionTips":["Validate vectors with isFiniteVector() at export time, not import time","Serialize with strict JSON (allow_nan=False in Python) so NaN/Infinity never reach the file","Log row ids alongside validation failures so bad rows can be traced back"],"tags":["database","postgresql","embeddings","sql-injection","validation"],"backgroundTag":"invalid-vector-data","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"}