{"record":{"id":"6073042cedfb2d4a","repo":"chroma-core/chroma","slug":"or-must-be-a-non-empty-array","errorCode":null,"errorMessage":"$or must be a non-empty array","messagePattern":"\\$or must be a non-empty array","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/where.ts","lineNumber":191,"sourceCode":"    });\n    if (conditions.length === 1) {\n      return conditions[0];\n    }\n    return conditions\n      .slice(1)\n      .reduce(\n        (acc, condition) => AndWhere.combine(acc, condition),\n        conditions[0],\n      );\n  }\n\n  if (\"$or\" in data) {\n    if (Object.keys(data).length !== 1) {\n      throw new Error(\"$or cannot be combined with other keys\");\n    }\n    const rawConditions = data[\"$or\"];\n    if (!Array.isArray(rawConditions) || rawConditions.length === 0) {\n      throw new TypeError(\"$or 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(\n        (acc, condition) => OrWhere.combine(acc, condition),\n        conditions[0],\n      );\n  }","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/where.ts#L173-L209","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst where = { $or: clauses }; // clauses may be [] -> TypeError\nawait collection.query({ queryTexts: ['x'], where });\n\n// after\nconst where = clauses.length === 0 ? undefined :\n  clauses.length === 1 ? clauses[0] : { $or: clauses };\nawait collection.query({ queryTexts: ['x'], where });","handlingStrategy":"validation","validationCode":"function buildOr(clauses: unknown[]): Record<string, unknown> | undefined {\n  const valid = clauses.filter((c) => c !== null && c !== undefined);\n  if (valid.length === 0) return undefined; // omit the filter entirely\n  if (valid.length === 1) return valid[0] as Record<string, unknown>;\n  return { $or: valid };\n}","typeGuard":"function isValidOrWhere(where: unknown): boolean {\n  if (typeof where !== 'object' || where === null) return true;\n  if ('$or' in where) {\n    const v = (where as Record<string, unknown>).$or;\n    return Array.isArray(v) && v.length > 0;\n  }\n  return true;\n}","tryCatchPattern":"try {\n  await collection.query({ queryTexts, where });\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('$or')) {\n    // rebuild the filter without the empty $or and retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["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."],"tags":["where-filter","query-validation","chroma","javascript"],"backgroundTag":"invalid-where-clause","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}