chroma-core/chroma · error · ChromaValueError
Expected 'where' to have exactly one operator, but got ${Obj
Error message
Expected 'where' to have exactly one operator, but got ${Object.keys(where).length} What it means
After the type gate, validateWhere requires exactly one key at the top level of the where object. Chroma's filter grammar allows a single field comparison or a single logical operator ($and/$or) per level; two or more sibling keys such as { a: 1, b: 2 } throw ChromaValueError. Multiple conditions must be combined explicitly with $and or $or.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:539
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)
) {
throw new ChromaValueError(
`Expected 'where' value to be a string, number, boolean, or an operator expression, but got ${value}`,
);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- Wrap multiple conditions: where: { $and: [{ genre: 'sci-fi' }, { year: 2020 }] }.
- Compose facet filters by pushing into a $and array instead of merging objects.
- Ensure the object has exactly one top-level key; use $and's array grammar for everything else.
Example fix
// before
where: { genre: 'sci-fi', year: 2020 }
// after
where: { $and: [{ genre: 'sci-fi' }, { year: 2020 }] } Defensive patterns
Strategy: validation
Validate before calling
const combine = (clauses) => clauses.length === 1 ? clauses[0] : { $and: clauses };
const where = combine([{ genre: 'sci-fi' }, { year: 2020 }]);
await collection.query({ queryTexts, where }); Type guard
const isSingleKey = (w: object) => Object.keys(w).length === 1;
Try / catch
try {
await collection.query({ queryTexts, where });
} catch (e) {
if ((e as Error).message.includes('exactly one operator')) {
// rebuild as { $and: [...] } from the sibling keys and retry
} else {
throw e;
}
} Prevention
- Never merge filter objects with Object.assign/spread — push clauses into a $and array.
- Remember Chroma allows exactly one top-level key per where level.
- Use a filter-builder helper that enforces the grammar.
When it happens
Trigger: where: { genre: 'sci-fi', year: 2020 } (two fields at top level). Building filters by Object.assign of several single-field filters. where: {} fails the same check with 0 keys.
Common situations: Coming from SQL (WHERE a AND b) or Mongo (where multiple top-level keys mean AND); composing filters from user-selected facets by merging objects.
Related errors
- Expected where to be a non-empty object
- Expected where to be a dict, got {where}
- Expected where to have exactly one operator, got {where}
- Expected 'where' value to be a string, number, boolean, or a
- Expected 'where' value for $and or $or to be a list of 'wher
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/dfa4f8fc1da509e7.
Report an issue: GitHub.