{"record":{"id":"d3d4fb8e9ec6f3d0","repo":"chroma-core/chroma","slug":"where-dictionary-must-contain-exactly-one-field","errorCode":null,"errorMessage":"Where dictionary must contain exactly one field","messagePattern":"Where dictionary must contain exactly one field","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/where.ts","lineNumber":213,"sourceCode":"      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  }\n\n  const entries = Object.entries(data);\n  if (entries.length !== 1) {\n    throw new Error(\"Where dictionary must contain exactly one field\");\n  }\n\n  const [field, value] = entries[0];\n  if (!isPlainObject(value)) {\n    return new ComparisonWhere(field, \"$eq\", value);\n  }\n\n  const operatorEntries = Object.entries(value);\n  if (operatorEntries.length !== 1) {\n    throw new Error(\n      `Operator dictionary for field \"${field}\" must contain exactly one operator`,\n    );\n  }\n\n  const [operator, operand] = operatorEntries[0];\n  const factory = comparisonOperatorMap.get(operator);\n  if (!factory) {\n    throw new Error(`Unsupported where operator: ${operator}`);","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/where.ts#L195-L231","documentation":"Chroma's where grammar allows exactly one field (or one logical operator) per dictionary level: each dict is either { $and/$or: [...] } or { field: value }. A dictionary with zero or multiple field keys — like { category: 'news', status: 'active' } or {} — fails parsing with this error before any request is sent. Multiple conditions must be combined with $and/$or or the fluent .and() builder.","triggerScenarios":"where: { category: 'news', status: 'active' }; merging two valid one-field dicts with object spread ({ ...filterA, ...filterB }); where: {} (zero entries also fails the exactly-one check); pasting a MongoDB-style multi-field query verbatim.","commonSituations":"Combining independent filters with object spread — a JS idiom that works for Mongo-style APIs but violates Chroma's one-key-per-level grammar; migrating from the Python client or Mongo where multi-field dicts are legal; building filters from generic key/value config maps.","solutions":["Wrap each condition in its own dict and combine: { $and: [{ category: 'news' }, { status: 'active' }] }.","Or use the builder: WhereExpression.from({ category: 'news' }).and({ status: 'active' }).","Replace object-spread merging of filters with an array of clauses reduced into { $and: clauses }.","Drop empty dicts ({}): skip filters that resolved to nothing instead of merging them in."],"exampleFix":"// before\nwhere: { ...categoryFilter, ...statusFilter } // { category: 'news', status: 'active' }\n\n// after\nwhere: { $and: [categoryFilter, statusFilter] } // one field per dict","handlingStrategy":"validation","validationCode":"function toChromaWhere(filters: Record<string, unknown>[]): Record<string, unknown> | undefined {\n  const clauses = filters.filter((f) => Object.keys(f).length === 1);\n  if (clauses.length !== filters.length) {\n    throw new Error('Each filter dict must contain exactly one field');\n  }\n  if (clauses.length === 0) return undefined;\n  if (clauses.length === 1) return clauses[0];\n  return { $and: clauses };\n}","typeGuard":"function isSingleFieldDict(where: unknown): boolean {\n  return (\n    typeof where === 'object' &&\n    where !== null &&\n    !Array.isArray(where) &&\n    Object.keys(where).length === 1\n  );\n}","tryCatchPattern":"try {\n  await collection.query({ where });\n} catch (e) {\n  if (e instanceof Error && e.message === 'Where dictionary must contain exactly one field') {\n    // split where into one-field dicts and rewrap as { $and: [...] }\n  } else {\n    throw e;\n  }\n}","preventionTips":["Never merge Chroma where dicts with object spread; collect them into an $and/$or array instead.","Keep one shared helper that reduces a list of single-field filters into valid Chroma shape.","Remember the grammar: one key per level; nesting replaces multi-field dicts."],"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"}