chroma-core/chroma · error · TypeError
Select keys must be strings or Key instances
Error message
Select keys must be strings or Key instances
What it means
Thrown by the Select constructor in the Chroma JS client (select.ts:20) when an entry in the keys iterable is neither a string nor a Key instance. Key instances are unwrapped to their .name; anything else — numbers, null, objects, arrays — throws. Keys are also deduplicated into a Set, so only the type of each entry matters.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/select.ts:20
export type SelectKeyInput = string | Key;
export type SelectInput =
| Select
| Iterable<SelectKeyInput>
| { keys?: Iterable<SelectKeyInput> }
| null
| undefined;
export class Select {
private readonly keys: string[];
constructor(keys: Iterable<SelectKeyInput> = []) {
const unique = new Set<string>();
for (const key of keys) {
const normalized = key instanceof Key ? key.name : key;
if (typeof normalized !== "string") {
throw new TypeError("Select keys must be strings or Key instances");
}
unique.add(normalized);
}
this.keys = Array.from(unique);
}
public static from(input: SelectInput): Select {
if (input instanceof Select) {
return new Select(input.keys);
}
if (input === null || input === undefined) {
return new Select();
}
if (Symbol.iterator in Object(input)) {
return new Select(input as Iterable<SelectKeyInput>);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Use plain strings: new Select(['#document', 'metadata_field'])
- Use the K factory or Key constants: Select.from([Key.DOCUMENT, K('tags')])
- Sanitize dynamic lists first: keys.filter(k => typeof k === 'string' || k instanceof Key)
Example fix
// before
const select = Select.from(['document', meta.fieldId, null]); // non-strings throw
// after
const select = Select.from(
['document', meta.fieldId, null].filter(
(k): k is string => typeof k === 'string',
),
); Defensive patterns
Strategy: type-guard
Validate before calling
const isSelectKey = (v: unknown): v is string => typeof v === 'string'; const safeKeys = rawKeys .map(k => (k instanceof Key ? k.name : k)) .filter(isSelectKey); const select = Select.from(safeKeys);
Type guard
const isSelectKeyInput = (v: unknown): v is string | Key => typeof v === 'string' || v instanceof Key;
Try / catch
try {
const select = Select.from(keys);
} catch (e) {
if (e instanceof TypeError && e.message.includes('Select keys')) {
return Select.from(keys.filter(isSelectKeyInput));
}
throw e;
} Prevention
- Express select fields as strings or K('field')/Key constants
- Map Key-like objects to their .name string when data crosses package boundaries
- Filter untrusted key lists (nulls from JSON) before Select.from
When it happens
Trigger: new Select(['document', 42]); Select.from([null]); Select.from([{ name: 'doc' }]) — passing key-like plain objects instead of Key instances or strings; select: [1, 2] from code that used numeric column indices from another API.
Common situations: Migrating from an ORM or SQL mindset where columns are referenced by index; JSON configs listing select fields where a value is null or numeric; mixed arrays produced by mapping over heterogeneous data; key objects imported from a different copy of the chromadb package (instanceof fails across duplicated classes), which then need .name passed explicitly.
Related errors
- Knn key must be a string or Key instance
- Unsupported select input
- Where input must be a WhereExpression or plain object
- Knn limit must be a positive integer
- Rrf k must be a positive integer
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/a2020bc3edb6531e.
Report an issue: GitHub.