chroma-core/chroma · error · ChromaValueError
Expected where to be a non-empty object
Error message
Expected where to be a non-empty object
What it means
validateWhere rejects a where argument whose typeof is not 'object'. This is a type gate: strings, numbers, booleans, and other non-object filters throw ChromaValueError immediately, client-side. Subsequent checks require exactly one top-level key, so the where clause must be a single-key operator object.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:535
export const validateMaxBatchSize = (
recordSetLength: number,
maxBatchSize: number,
) => {
if (recordSetLength > maxBatchSize) {
throw new ChromaValueError(
`Record set length ${recordSetLength} exceeds max batch size ${maxBatchSize}`,
);
}
};
/**
* Validates a where clause for metadata filtering.
* @param where - Where clause object to validate
* @throws ChromaValueError if the where clause is malformed
*/
export const validateWhere = (where: Where) => {
if (typeof where !== "object") {
throw new ChromaValueError("Expected where to be a non-empty object");
}
if (Object.keys(where).length != 1) {
throw new ChromaValueError(
`Expected 'where' to have exactly one operator, but got ${
Object.keys(where).length
}`,
);
}
Object.entries(where).forEach(([key, value]) => {
if (
key !== "$and" &&
key !== "$or" &&
key !== "$in" &&
key !== "$nin" &&
!["string", "number", "boolean", "object"].includes(typeof value)
) {View on GitHub (pinned to aecdd12c8a)
Solutions
- Pass a structured object: where: { genre: 'sci-fi' } or where: { $and: [ ... ] }.
- Parse JSON strings before use: where: JSON.parse(raw).
- Omit the where option entirely when no filtering is needed — do not pass a primitive placeholder.
Example fix
// before
await collection.query({ queryTexts: ['x'], where: 'genre = sci-fi' });
// after
await collection.query({ queryTexts: ['x'], where: { genre: 'sci-fi' } }); Defensive patterns
Strategy: type-guard
Validate before calling
if (where !== undefined && (typeof where !== 'object' || where === null)) {
throw new TypeError('where must be an object like { field: value } or { $and: [...] }');
}
await collection.query({ queryTexts, where }); Type guard
const isWhere = (w: unknown): w is Record<string, unknown> => typeof w === 'object' && w !== null && !Array.isArray(w);
Try / catch
try {
await collection.query({ queryTexts, where });
} catch (e) {
if ((e as Error).message.includes('where to be a non-empty object')) {
// fix the where shape to an object, or omit it and retry
} else {
throw e;
}
} Prevention
- Build filters as structured objects, never strings.
- Parse JSON filter payloads before passing them.
- Omit the where option when no filtering is needed.
When it happens
Trigger: collection.query({ where: 'genre = sci-fi' }) — passing a raw SQL-ish string. where: 123. Spreading a string variable into the where option by mistake.
Common situations: Translating SQL or Mongo-like filter strings into Chroma's structured filters; a filter builder returning a primitive when no criteria exist; passing a serialized JSON string instead of a parsed object.
Related errors
- Expected 'where' to have exactly one operator, but got ${Obj
- Expected where to be a dict, got {where}
- Expected where to have exactly one operator, got {where}
- $or must be a non-empty array
- Where dictionary must contain exactly one field
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/1f5fd49cc019e178.
Report an issue: GitHub.