chroma-core/chroma · error · TypeError
${message}
Error message
${message} What it means
This is the shared requireNumber guard in rank.ts: it throws a TypeError with a caller-supplied message whenever a value is not a number, NaN, or non-finite (Infinity/-Infinity). The concrete messages you will see are "Val requires a numeric value" (from Val(value)) and "Knn default must be a number" (from Knn({ default })). It exists because JS callers and any-typed values can bypass the TypeScript number signatures.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/rank.ts:19
import type { SparseVector } from "../../api";
import { deepClone, isPlainObject, IterableInput } from "./common";
import { Key } from "./key";
export type RankLiteral = Record<string, unknown>;
export type RankInput =
| RankExpression
| RankLiteral
| number
| null
| undefined;
const requireNumber = (value: unknown, message: string): number => {
if (
typeof value !== "number" ||
Number.isNaN(value) ||
!Number.isFinite(value)
) {
throw new TypeError(message);
}
return value;
};
abstract class RankExpressionBase {
public abstract toJSON(): Record<string, unknown>;
public add(...others: RankInput[]): RankExpression {
if (others.length === 0) {
return this as unknown as RankExpression;
}
const expressions = [
this as unknown as RankExpression,
...others.map((item, index) => requireRank(item, `add operand ${index}`)),
];
return SumRankExpression.create(expressions);
}
View on GitHub (pinned to aecdd12c8a)
Solutions
- Coerce before calling: Val(Number(weight)) with an explicit fallback for NaN
- Validate finiteness at the source: if (!Number.isFinite(x)) use a default
- For Knn defaults, pass a literal number (e.g. 0) or omit/null the option entirely
Example fix
// before const boost = Val(cfg.weight); // cfg.weight = "1.5" (string) -> TypeError // after const weight = Number(cfg.weight); const boost = Val(Number.isFinite(weight) ? weight : 1);
Defensive patterns
Strategy: validation
Validate before calling
const toFiniteNumber = (v: unknown, fallback: number): number =>
typeof v === "number" && Number.isFinite(v) ? v : fallback;
const boost = Val(toFiniteNumber(cfg.weight, 1));
const knn = Knn({ query, default: toFiniteNumber(cfg.defaultScore, 0) }); Type guard
const isFiniteNumber = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v);
Try / catch
try {
const expr = Val(weight);
} catch (e) {
if (e instanceof TypeError && /numeric value|must be a number/.test(e.message)) {
// coerce the source value (Number()) or substitute a default and rebuild
} else throw e;
} Prevention
- Coerce config/LLM-sourced numbers with Number() and check Number.isFinite before Val()/Knn default
- Watch for x / 0 producing Infinity upstream
- Type rank weights as number at the config schema level
When it happens
Trigger: Val(NaN), Val("1.5"), or Val(Infinity) when building rank constants. Knn({ query, default: "0" }) or Knn({ default: NaN }) when supplying a default score for records missing embeddings.
Common situations: Rank weights parsed from config or LLM output as strings ("1.5") instead of numbers. Division producing Infinity (x / 0) before feeding Val(). optional-chained values that turn out to be undefined and are passed as the Knn default.
Related errors
- Dense query vector values must be finite numbers
- MinK k must be positive
- MaxK k must be positive
- Limit offset must be a non-negative integer
- Limit must be a positive integer when provided
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/af3929bdbc16a844.
Report an issue: GitHub.