chroma-core/chroma · error · ChromaValueError
Expected 'whereDocument' to be a non-empty object
Error message
Expected 'whereDocument' to be a non-empty object
What it means
validateWhereDocument is the whereDocument counterpart of the where type gate: a non-object value (string, number, etc.) throws ChromaValueError. whereDocument must be an object with exactly one operator (e.g. $contains) whose operand is a string. Passing raw search text directly is the classic mistake.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:651
(operand.length === 0 ||
!operand.every((item) => typeof item === typeof operand[0]))
) {
throw new ChromaValueError(
"Expected 'where' operand value to be a non-empty list and all values to be of the same type",
);
}
}
});
};
/**
* Validates a where document clause for document content filtering.
* @param whereDocument - Where document clause to validate
* @throws ChromaValueError if the clause is malformed
*/
export const validateWhereDocument = (whereDocument: WhereDocument) => {
if (typeof whereDocument !== "object") {
throw new ChromaValueError(
"Expected 'whereDocument' to be a non-empty object",
);
}
if (Object.keys(whereDocument).length != 1) {
throw new ChromaValueError(
`Expected 'whereDocument' to have exactly one operator, but got ${whereDocument}`,
);
}
const [operator, operand] = Object.entries(whereDocument)[0];
if (
![
"$contains",
"$not_contains",
"$matches",
"$not_matches",
"$regex",View on GitHub (pinned to aecdd12c8a)
Solutions
- Wrap text in an operator: whereDocument: { $contains: 'machine learning' }.
- Parse JSON strings before passing them.
- Use queryTexts or queryEmbeddings for semantic search — whereDocument is only for content filtering.
Example fix
// before
await collection.query({ queryTexts: ['ai'], whereDocument: 'machine learning' });
// after
await collection.query({ queryTexts: ['ai'], whereDocument: { $contains: 'machine learning' } }); Defensive patterns
Strategy: type-guard
Validate before calling
if (whereDocument !== undefined && (typeof whereDocument !== 'object' || whereDocument === null)) {
throw new TypeError('whereDocument must be like { $contains: \'text\' }');
}
await collection.query({ queryTexts, whereDocument }); Type guard
const isWhereDocument = (w: unknown): w is { $contains?: string; $not_contains?: string } =>
typeof w === 'object' && w !== null && !Array.isArray(w); Try / catch
try {
await collection.query({ queryTexts, whereDocument });
} catch (e) {
if ((e as Error).message.includes('whereDocument')) {
// wrap the raw text as { $contains: text } and retry
} else {
throw e;
}
} Prevention
- Always wrap document filter text in { $contains: ... }.
- Use queryTexts for semantic search; whereDocument only narrows by content.
- Parse serialized filter objects before passing them to query().
When it happens
Trigger: collection.query({ whereDocument: 'machine learning' }) — raw string. whereDocument: 42. A JSON string that was never parsed.
Common situations: Assuming whereDocument takes search text directly; wiring a search box input straight into the option; confusing content filtering (whereDocument) with semantic search (queryTexts).
Related errors
- Expected where to be a non-empty object
- Expected 'where' to have exactly one operator, but got ${Obj
- Expected 'whereDocument' to have exactly one operator, but g
- Expected 'whereDocument' operator to be one of $contains, $n
- Expected operand for ${operator} to be a list of 'whereDocum
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/c0701fdbab775fa4.
Report an issue: GitHub.