chroma-core/chroma · error · Error
$and cannot be combined with other keys
Error message
$and cannot be combined with other keys
What it means
Thrown by parseWhereDict (where.ts:161) when a where dict contains an $and key alongside any other key. The parser requires $and to be the sole key in its object — the JSON grammar it emits is { $and: [clause, clause, ...] }. This mirrors the same rule in Chroma's Python client and is a plain Error (not a TypeError).
Source
Thrown at clients/new-js/packages/chromadb/src/execution/expression/where.ts:161
["$gt", (key, value) => new ComparisonWhere(key, "$gt", value)],
["$gte", (key, value) => new ComparisonWhere(key, "$gte", value)],
["$lt", (key, value) => new ComparisonWhere(key, "$lt", value)],
["$lte", (key, value) => new ComparisonWhere(key, "$lte", value)],
["$in", (key, value) => new ComparisonWhere(key, "$in", value)],
["$nin", (key, value) => new ComparisonWhere(key, "$nin", value)],
["$contains", (key, value) => new ComparisonWhere(key, "$contains", value)],
[
"$not_contains",
(key, value) => new ComparisonWhere(key, "$not_contains", value),
],
["$regex", (key, value) => new ComparisonWhere(key, "$regex", value)],
["$not_regex", (key, value) => new ComparisonWhere(key, "$not_regex", value)],
]);
const parseWhereDict = (data: Record<string, unknown>): WhereExpression => {
if ("$and" in data) {
if (Object.keys(data).length !== 1) {
throw new Error("$and cannot be combined with other keys");
}
const rawConditions = data["$and"];
if (!Array.isArray(rawConditions) || rawConditions.length === 0) {
throw new TypeError("$and 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(View on GitHub (pinned to aecdd12c8a)
Solutions
- Move sibling conditions into the $and array: { $and: [condA, condB, { status: { $eq: 'active' } }] }
- Or build filters programmatically with WhereExpression .and(), which nests correctly for you
- When merging user filters, wrap: { $and: [...existingClauses, newClause] }
Example fix
// before
const where = { $and: [{ a: 1 }, { b: 2 }], channel: { $eq: 'email' } };
// after
const where = {
$and: [{ a: 1 }, { b: 2 }, { channel: { $eq: 'email' } }],
}; Defensive patterns
Strategy: validation
Validate before calling
const combine = (clauses: Record<string, unknown>[]): Record<string, unknown> =>
clauses.length > 1 ? { $and: clauses } : clauses[0];
// never spread extra keys next to $and Try / catch
try {
const results = await collection.query({ where });
} catch (e) {
if (e instanceof Error && e.message.includes('$and cannot be combined')) {
const { $and, ...rest } = where;
const key = Object.keys(rest)[0];
return collection.query({
where: { $and: [...($and as object[]), { [key]: rest[key] }] },
});
}
throw e;
} Prevention
- Treat $and as a container: everything it combines lives inside its array
- When merging filters, push clauses into the $and array instead of spreading objects
- Use WhereExpression .and() for programmatic combination
When it happens
Trigger: Passing { $and: [condA, condB], status: { $eq: 'active' } } — the sibling condition must move inside the $and list; also { $and: [...], $or: [...] } in one object, since $and is checked first and any second key triggers the error.
Common situations: Developers appending an extra filter to an existing $and dict instead of extending the array; merging filter objects with spread ({...base, extra}) where base already had $and; translating SQL WHERE a AND b AND c into mixed shorthand rather than a flat $and list.
Related errors
- $and must be a non-empty array
- Invalid where clause at index ${index}
- $or cannot be combined with other keys
- Where input must be a WhereExpression or plain object
- Expected document value for $and or $or to be a list with at
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/182d1bca43a82bc8.
Report an issue: GitHub.