chroma-core/chroma · error · TypeError
Knn key must be a string or Key instance
Error message
Knn key must be a string or Key instance
What it means
Thrown by normalizeKnnOptions in the Chroma JS client (rank.ts:410) when Knn()'s `key` option is neither a string nor a Key instance. The key names the field to search (default '#embedding'); a Key instance is unwrapped to its .name. Note the fallback `options.key ?? '#embedding'` only substitutes for null/undefined — any other non-string value (0, false, {}, []) reaches the typeof check and throws.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/rank.ts:410
query = queryInput;
} else if (
isPlainObject(queryInput) &&
Array.isArray((queryInput as SparseVector).indices) &&
Array.isArray((queryInput as SparseVector).values)
) {
const sparse = queryInput as SparseVector;
query = {
indices: sparse.indices.slice(),
values: sparse.values.slice(),
};
} else {
query = normalizeDenseVector(queryInput as IterableInput<number>);
}
const key =
options.key instanceof Key ? options.key.name : options.key ?? "#embedding";
if (typeof key !== "string") {
throw new TypeError("Knn key must be a string or Key instance");
}
const defaultValue =
options.default === null || options.default === undefined
? undefined
: requireNumber(options.default, "Knn default must be a number");
if (defaultValue !== undefined && !Number.isFinite(defaultValue)) {
throw new TypeError("Knn default must be a finite number");
}
return {
query:
Array.isArray(query) || typeof query === "string"
? query
: deepClone(query),
key,
limit,View on GitHub (pinned to aecdd12c8a)
Solutions
- Pass a string field name: Knn({ query, key: 'my_embedding' })
- Or pass a Key instance built with the same library version: Knn({ query, key: K('my_embedding') }) or Key.EMBEDDING
- If the key comes from dynamic data, normalize it first: typeof k === 'string' || k instanceof Key ? k : '#embedding'
Example fix
// before
const rank = Knn({ query: vec, key: 0 }); // throws: not nullish, not a string
// after
const rank = Knn({ query: vec, key: K('my_embedding') });
// or simply omit key to search '#embedding' Defensive patterns
Strategy: type-guard
Validate before calling
const normalizeKnnKey = (k: unknown): string | Key =>
k instanceof Key || typeof k === 'string' ? (k as string | Key) : '#embedding';
const rank = Knn({ query: vec, key: normalizeKnnKey(cfg.key) }); Type guard
const isKeyLike = (v: unknown): v is string | Key => v == null || typeof v === 'string' || v instanceof Key;
Try / catch
try {
const rank = Knn({ query: vec, key });
} catch (e) {
if (e instanceof TypeError && e.message.includes('Knn key')) {
return Knn({ query: vec, key: K('my_embedding') });
}
throw e;
} Prevention
- Use K('field') or the Key constants so types are guaranteed
- Remember `??` only covers null/undefined: key: 0 or key: false still throw
- Keep a single copy of the chromadb package — instanceof Key fails across duplicated versions
When it happens
Trigger: Calling Knn({ query, key: 0 }) or key: false (falsy but not nullish, so the ?? fallback does not apply); key: { name: 'emb' } or key: ['emb'] (plain object/array instead of Key/string); key computed from a lookup that returns a number or undefined-turned-wrong-type via type coercion.
Common situations: Mixing up metadata field names that are numeric IDs with Key objects; passing a Key-like object from another library version (e.g. after a package upgrade where Key is a different class instance); copying Python-client snippets where keys can be other types; storing keys in config as non-strings.
Related errors
- Knn limit must be a positive integer
- Select keys must be strings or Key instances
- Where input must be a WhereExpression or plain object
- Knn default must be a finite number
- Rrf k must be a positive integer
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/88702006d1896633.
Report an issue: GitHub.