{"record":{"id":"9e2a39cd2ad9d366","repo":"chroma-core/chroma","slug":"dense-query-vector-values-must-be-finite-numbers","errorCode":null,"errorMessage":"Dense query vector values must be finite numbers","messagePattern":"Dense query vector values must be finite numbers","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/rank.ts","lineNumber":376,"sourceCode":"export interface KnnOptions {\n  query: IterableInput<number> | SparseVector | string;\n  key?: string | Key;\n  limit?: number;\n  default?: number | null;\n  returnRank?: boolean;\n}\n\nconst normalizeDenseVector = (vector: IterableInput<number>): number[] => {\n  if (Array.isArray(vector)) {\n    return vector.slice();\n  }\n  return Array.from(vector as Iterable<number>, (value) => {\n    if (\n      typeof value !== \"number\" ||\n      Number.isNaN(value) ||\n      !Number.isFinite(value)\n    ) {\n      throw new TypeError(\"Dense query vector values must be finite numbers\");\n    }\n    return value;\n  });\n};\n\nconst normalizeKnnOptions = (options: KnnOptions): KnnOptionsNormalized => {\n  const limit = options.limit ?? 128;\n  if (!Number.isInteger(limit) || limit <= 0) {\n    throw new TypeError(\"Knn limit must be a positive integer\");\n  }\n\n  const queryInput = options.query;\n\n  let query: number[] | SparseVector | string;\n  if (typeof queryInput === \"string\") {\n    query = queryInput;\n  } else if (\n    isPlainObject(queryInput) &&","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/rank.ts#L358-L394","documentation":"When Knn() receives a non-array iterable (Set, generator, custom iterator) as the dense query vector, normalizeDenseVector checks every yielded element and throws this TypeError if any is not a finite number (NaN, Infinity, strings, null all fail). Note the asymmetry: plain arrays are copied with slice() and NOT element-checked here, so this client-side error surfaces specifically for iterable inputs — bad arrays instead fail later, server-side.","triggerScenarios":"Knn({ query: new Set([0.1, NaN]) }); Knn({ query: someGenerator() }) where the generator yields \"0.1\" (string) or null for missing dimensions; an iterator over parsed CSV/JSONL rows whose numbers became strings.","commonSituations":"Embeddings loaded from JSON/CSV where values deserialize as strings. Generators or Sets built from user uploads containing empty cells (null). Upstream embedding services returning NaN for failed dimensions. Passing a single number or nested arrays via an iterator by mistake.","solutions":["Materialize and sanitize before calling Knn: Array.from(iterable).map(Number) and verify every element is finite","Validate with numbers.every((v) => Number.isFinite(v)) and reject/repair bad vectors at load time","Ensure embedding pipelines emit actual numbers — parse string sources and replace missing values explicitly"],"exampleFix":"// before\nconst q = Knn({ query: parseRows(file) }); // generator yields \"0.1\" strings -> TypeError\n\n// after\nconst raw = Array.from(parseRows(file), Number);\nif (!raw.every((v) => Number.isFinite(v))) throw new Error(\"Bad embedding vector\");\nconst q = Knn({ query: raw });","handlingStrategy":"validation","validationCode":"const queryVector = Array.from(queryIterable, (v) => (typeof v === \"string\" ? Number(v) : v));\nif (!queryVector.every((v) => typeof v === \"number\" && Number.isFinite(v))) {\n  throw new Error(\"Query vector contains non-finite values — check the embedding source\");\n}\nconst knn = Knn({ query: queryVector });","typeGuard":"const isDenseVector = (v: unknown): v is number[] =>\n  Array.isArray(v) && v.every((x) => typeof x === \"number\" && Number.isFinite(x));","tryCatchPattern":"try {\n  const knn = Knn({ query: vectorSource() });\n} catch (e) {\n  if (e instanceof TypeError && /finite numbers/.test(e.message)) {\n    // materialize, sanitize (map Number, replace NaN), and rebuild the Knn expression\n  } else throw e;\n}","preventionTips":["Materialize iterables to arrays and validate every element with Number.isFinite before Knn","Parse string-typed values from JSON/CSV sources with Number() at load time","Check embedding services for NaN/Infinity outputs before queries — plain arrays skip client validation and fail server-side instead"],"tags":["chroma","knn","embedding-vector","numeric"],"backgroundTag":"nan-in-numeric-input","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}