chroma-core/chroma · error · TypeError

Dense query vector values must be finite numbers

Error message

Dense query vector values must be finite numbers

What it means

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.

Source

Thrown at clients/new-js/packages/chromadb/src/execution/expression/rank.ts:376

export interface KnnOptions {
  query: IterableInput<number> | SparseVector | string;
  key?: string | Key;
  limit?: number;
  default?: number | null;
  returnRank?: boolean;
}

const normalizeDenseVector = (vector: IterableInput<number>): number[] => {
  if (Array.isArray(vector)) {
    return vector.slice();
  }
  return Array.from(vector as Iterable<number>, (value) => {
    if (
      typeof value !== "number" ||
      Number.isNaN(value) ||
      !Number.isFinite(value)
    ) {
      throw new TypeError("Dense query vector values must be finite numbers");
    }
    return value;
  });
};

const normalizeKnnOptions = (options: KnnOptions): KnnOptionsNormalized => {
  const limit = options.limit ?? 128;
  if (!Number.isInteger(limit) || limit <= 0) {
    throw new TypeError("Knn limit must be a positive integer");
  }

  const queryInput = options.query;

  let query: number[] | SparseVector | string;
  if (typeof queryInput === "string") {
    query = queryInput;
  } else if (
    isPlainObject(queryInput) &&

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Materialize and sanitize before calling Knn: Array.from(iterable).map(Number) and verify every element is finite
  2. Validate with numbers.every((v) => Number.isFinite(v)) and reject/repair bad vectors at load time
  3. Ensure embedding pipelines emit actual numbers — parse string sources and replace missing values explicitly

Example fix

// before
const q = Knn({ query: parseRows(file) }); // generator yields "0.1" strings -> TypeError

// after
const raw = Array.from(parseRows(file), Number);
if (!raw.every((v) => Number.isFinite(v))) throw new Error("Bad embedding vector");
const q = Knn({ query: raw });
Defensive patterns

Strategy: validation

Validate before calling

const queryVector = Array.from(queryIterable, (v) => (typeof v === "string" ? Number(v) : v));
if (!queryVector.every((v) => typeof v === "number" && Number.isFinite(v))) {
  throw new Error("Query vector contains non-finite values — check the embedding source");
}
const knn = Knn({ query: queryVector });

Type guard

const isDenseVector = (v: unknown): v is number[] =>
  Array.isArray(v) && v.every((x) => typeof x === "number" && Number.isFinite(x));

Try / catch

try {
  const knn = Knn({ query: vectorSource() });
} catch (e) {
  if (e instanceof TypeError && /finite numbers/.test(e.message)) {
    // materialize, sanitize (map Number, replace NaN), and rebuild the Knn expression
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/9e2a39cd2ad9d366. Report an issue: GitHub.