{"record":{"id":"8a36f0e75b0415a1","repo":"chroma-core/chroma","slug":"expected-where-value-to-be-a-string-number-boo","errorCode":null,"errorMessage":"Expected 'where' value to be a string, number, boolean, or an operator expression, but got ${value}","messagePattern":"Expected 'where' value to be a string, number, boolean, or an operator expression, but got (.+?)","errorType":"validation","errorClass":"ChromaValueError","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/utils.ts","lineNumber":554,"sourceCode":"  }\n\n  if (Object.keys(where).length != 1) {\n    throw new ChromaValueError(\n      `Expected 'where' to have exactly one operator, but got ${\n        Object.keys(where).length\n      }`,\n    );\n  }\n\n  Object.entries(where).forEach(([key, value]) => {\n    if (\n      key !== \"$and\" &&\n      key !== \"$or\" &&\n      key !== \"$in\" &&\n      key !== \"$nin\" &&\n      ![\"string\", \"number\", \"boolean\", \"object\"].includes(typeof value)\n    ) {\n      throw new ChromaValueError(\n        `Expected 'where' value to be a string, number, boolean, or an operator expression, but got ${value}`,\n      );\n    }\n\n    if (key === \"$and\" || key === \"$or\") {\n      if (Object.keys(value).length <= 1) {\n        throw new ChromaValueError(\n          `Expected 'where' value for $and or $or to be a list of 'where' expressions, but got ${value}`,\n        );\n      }\n\n      value.forEach((w: Where) => validateWhere(w));\n      return;\n    }\n\n    if (typeof value === \"object\") {\n      if (Object.keys(value).length != 1) {\n        throw new ChromaValueError(","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/utils.ts#L536-L572","documentation":"For a field key (not $and/$or/$in/$nin), validateWhere accepts only string, number, boolean, or object values — 'object' meaning an operator expression like { $gte: 10 }. Any other typeof (undefined, function, bigint, symbol) throws ChromaValueError. The message interpolates the value itself, which can look odd for functions.","triggerScenarios":"where: { field: undefined } — building filters from optional request params without stripping undefined. where: { field: () => true }. A BigInt operand (typeof 'bigint').","commonSituations":"Optional filter params passed straight from an HTTP query object; defaulting missing filters to undefined instead of removing the key; storing computed predicates in the filter object.","solutions":["Strip undefined values before the call: Object.fromEntries(Object.entries(f).filter(([, v]) => v != null)).","Only assign keys whose value is a scalar or a single-operator expression.","Type the filter with Chroma's Where type so the compiler rejects bad shapes."],"exampleFix":"// before\nwhere: { genre: req.query.genre } // genre is undefined\n\n// after\nconst entries = Object.entries({ genre: req.query.genre }).filter(([, v]) => v !== undefined);\nconst where = entries.length ? Object.fromEntries(entries) : undefined;","handlingStrategy":"type-guard","validationCode":"const clean = Object.fromEntries(\n  Object.entries(filter).filter(([, v]) => ['string', 'number', 'boolean', 'object'].includes(typeof v))\n);\nawait collection.query({ queryTexts, where: clean });","typeGuard":"const isWhereValue = (v: unknown): v is string | number | boolean | object =>\n  ['string', 'number', 'boolean', 'object'].includes(typeof v);","tryCatchPattern":"try {\n  await collection.query({ queryTexts, where });\n} catch (e) {\n  if ((e as Error).message.includes('operator expression, but got')) {\n    // strip undefined/function values from the where object and retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["Strip undefined values from filter objects built from request params.","Type filter builders with Chroma's Where type.","Never store functions or computed predicates inside a where object."],"tags":["where-filter","validation","type-error"],"backgroundTag":"invalid-where-clause","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}