chroma-core/chroma · error · TypeError
$or must be a non-empty array
Error message
$or must be a non-empty array
What it means
The Chroma JS client compiles every `where` filter into a WhereExpression tree before serializing it to the server. When a filter dictionary uses the `$or` key, its value must be an array containing at least one nested where clause (the same rule applies to `$and`). This TypeError is thrown client-side at parse time when the `$or` value is not an array at all, or is an empty array, so no network request is ever made.
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/where.ts:191
});
if (conditions.length === 1) {
return conditions[0];
}
return conditions
.slice(1)
.reduce(
(acc, condition) => AndWhere.combine(acc, condition),
conditions[0],
);
}
if ("$or" in data) {
if (Object.keys(data).length !== 1) {
throw new Error("$or cannot be combined with other keys");
}
const rawConditions = data["$or"];
if (!Array.isArray(rawConditions) || rawConditions.length === 0) {
throw new TypeError("$or must be a non-empty array");
}
const conditions = rawConditions.map((item, index) => {
const expr = WhereExpression.from(item as WhereInput);
if (!expr) {
throw new TypeError(`Invalid where clause at index ${index}`);
}
return expr;
});
if (conditions.length === 1) {
return conditions[0];
}
return conditions
.slice(1)
.reduce(
(acc, condition) => OrWhere.combine(acc, condition),
conditions[0],
);
}View on GitHub (pinned to aecdd12c8a)
Solutions
- If the dynamic condition list can be empty, omit the filter entirely: pass where: undefined (or leave the property out) when the list has zero clauses.
- If only one condition remains, pass it directly instead of wrapping: where: clauses[0], not { $or: [clauses[0]] } or { $or: clauses[0] }.
- Make sure the $or value is an array of clause objects: { $or: [{ status: 'active' }, { status: 'pending' }] }.
- If you meant a logical AND, use { $and: [...] } with the same non-empty-array rule.
Example fix
// before
const where = { $or: clauses }; // clauses may be [] -> TypeError
await collection.query({ queryTexts: ['x'], where });
// after
const where = clauses.length === 0 ? undefined :
clauses.length === 1 ? clauses[0] : { $or: clauses };
await collection.query({ queryTexts: ['x'], where }); Defensive patterns
Strategy: validation
Validate before calling
function buildOr(clauses: unknown[]): Record<string, unknown> | undefined {
const valid = clauses.filter((c) => c !== null && c !== undefined);
if (valid.length === 0) return undefined; // omit the filter entirely
if (valid.length === 1) return valid[0] as Record<string, unknown>;
return { $or: valid };
} Type guard
function isValidOrWhere(where: unknown): boolean {
if (typeof where !== 'object' || where === null) return true;
if ('$or' in where) {
const v = (where as Record<string, unknown>).$or;
return Array.isArray(v) && v.length > 0;
}
return true;
} Try / catch
try {
await collection.query({ queryTexts, where });
} catch (e) {
if (e instanceof TypeError && e.message.includes('$or')) {
// rebuild the filter without the empty $or and retry
} else {
throw e;
}
} Prevention
- Never spread an unbounded dynamic array straight into { $or: [...] }; coerce the empty case to undefined first.
- Treat $or/$and as arrays of one-field dictionaries; single-object shorthand is not supported by this client.
- Validate user-supplied filter JSON against the where grammar before passing it to query or count.
When it happens
Trigger: Calling collection.query with where: { $or: [] }; passing a single object instead of an array, e.g. where: { $or: { status: 'active' } }; building the $or list at runtime from a source array that happens to be empty (e.g. items.map(...).filter(...) with no matches).
Common situations: Dynamically composed filters where the OR branch is optional and sometimes empty; porting MongoDB/SQL OR syntax that permits an object shorthand or an empty disjunction; spreading user-supplied filter parts into { $or: parts } without checking parts.length.
Related errors
- Where dictionary must contain exactly one field
- Operator dictionary for field "${field}" must contain exactl
- Unsupported where operator: ${operator}
- K.DOCUMENT.contains requires a string value
- K.DOCUMENT.notContains requires a string value
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/6073042cedfb2d4a.
Report an issue: GitHub.