{"record":{"id":"182d1bca43a82bc8","repo":"chroma-core/chroma","slug":"and-cannot-be-combined-with-other-keys","errorCode":null,"errorMessage":"$and cannot be combined with other keys","messagePattern":"\\$and cannot be combined with other keys","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/where.ts","lineNumber":161,"sourceCode":"  [\"$gt\", (key, value) => new ComparisonWhere(key, \"$gt\", value)],\n  [\"$gte\", (key, value) => new ComparisonWhere(key, \"$gte\", value)],\n  [\"$lt\", (key, value) => new ComparisonWhere(key, \"$lt\", value)],\n  [\"$lte\", (key, value) => new ComparisonWhere(key, \"$lte\", value)],\n  [\"$in\", (key, value) => new ComparisonWhere(key, \"$in\", value)],\n  [\"$nin\", (key, value) => new ComparisonWhere(key, \"$nin\", value)],\n  [\"$contains\", (key, value) => new ComparisonWhere(key, \"$contains\", value)],\n  [\n    \"$not_contains\",\n    (key, value) => new ComparisonWhere(key, \"$not_contains\", value),\n  ],\n  [\"$regex\", (key, value) => new ComparisonWhere(key, \"$regex\", value)],\n  [\"$not_regex\", (key, value) => new ComparisonWhere(key, \"$not_regex\", value)],\n]);\n\nconst parseWhereDict = (data: Record<string, unknown>): WhereExpression => {\n  if (\"$and\" in data) {\n    if (Object.keys(data).length !== 1) {\n      throw new Error(\"$and cannot be combined with other keys\");\n    }\n    const rawConditions = data[\"$and\"];\n    if (!Array.isArray(rawConditions) || rawConditions.length === 0) {\n      throw new TypeError(\"$and must be a non-empty array\");\n    }\n    const conditions = rawConditions.map((item, index) => {\n      const expr = WhereExpression.from(item as WhereInput);\n      if (!expr) {\n        throw new TypeError(`Invalid where clause at index ${index}`);\n      }\n      return expr;\n    });\n    if (conditions.length === 1) {\n      return conditions[0];\n    }\n    return conditions\n      .slice(1)\n      .reduce(","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/where.ts#L143-L179","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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] }"],"exampleFix":"// before\nconst where = { $and: [{ a: 1 }, { b: 2 }], channel: { $eq: 'email' } };\n\n// after\nconst where = {\n  $and: [{ a: 1 }, { b: 2 }, { channel: { $eq: 'email' } }],\n};","handlingStrategy":"validation","validationCode":"const combine = (clauses: Record<string, unknown>[]): Record<string, unknown> =>\n  clauses.length > 1 ? { $and: clauses } : clauses[0];\n// never spread extra keys next to $and","typeGuard":null,"tryCatchPattern":"try {\n  const results = await collection.query({ where });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('$and cannot be combined')) {\n    const { $and, ...rest } = where;\n    const key = Object.keys(rest)[0];\n    return collection.query({\n      where: { $and: [...($and as object[]), { [key]: rest[key] }] },\n    });\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["where","and","query-filter","input-validation"],"backgroundTag":"invalid-query-filter","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}