chroma-core/chroma · error · ChromaValueError
Expected operand value to be an array for ${operator}, but g
Error message
Expected operand value to be an array for ${operator}, but got ${operand} What it means
$in and $nin require their operand to be an array; validateWhere throws when it is not. A scalar, object, or string value for these set-membership operators fails the Array.isArray check client-side. Wrap the value(s) in a list before the call.
Source
Thrown at clients/new-js/packages/chromadb/src/utils.ts:589
if (Object.keys(value).length != 1) {
throw new ChromaValueError(
`Expected operator expression to have one operator, but got ${value}`,
);
}
const [operator, operand] = Object.entries(value)[0];
if (
["$gt", "$gte", "$lt", "$lte"].includes(operator) &&
typeof operand !== "number"
) {
throw new ChromaValueError(
`Expected operand value to be a number for ${operator}, but got ${typeof operand}`,
);
}
if (["$in", "$nin"].includes(operator) && !Array.isArray(operand)) {
throw new ChromaValueError(
`Expected operand value to be an array for ${operator}, but got ${operand}`,
);
}
if (
["$contains", "$not_contains"].includes(operator) &&
!["string", "number", "boolean"].includes(typeof operand)
) {
throw new ChromaValueError(
`Expected operand value to be a string, number, or boolean for ${operator}, but got ${typeof operand}`,
);
}
if (
![
"$gt",
"$gte",
"$lt",View on GitHub (pinned to aecdd12c8a)
Solutions
- Always wrap: { $in: ['sci-fi'] }.
- Normalize inputs: const list = Array.isArray(v) ? v : [v].
- Use $eq for exact single matches instead of $in with a scalar.
Example fix
// before
where: { genre: { $in: selectedGenre } } // selectedGenre = 'sci-fi'
// after
where: { genre: { $in: Array.isArray(selectedGenre) ? selectedGenre : [selectedGenre] } } Defensive patterns
Strategy: validation
Validate before calling
const toList = (v) => Array.isArray(v) ? v : [v];
await collection.query({ queryTexts, where: { genre: { $in: toList(selected) } } }); Type guard
const isInOperand = (v: unknown): v is unknown[] => Array.isArray(v);
Try / catch
try {
await collection.query({ queryTexts, where });
} catch (e) {
if ((e as Error).message.includes('to be an array for')) {
// wrap the scalar in [ ] and retry
} else {
throw e;
}
} Prevention
- Normalize scalar-or-array inputs with an ensureArray() helper.
- Reserve $in/$nin for lists; use $eq for single values.
- Keep UI state for multi-selects always as arrays.
When it happens
Trigger: where: { genre: { $in: 'sci-fi' } } — single value not wrapped. { $nin: { genre: 'x' } }. A variable that is sometimes scalar: { $in: selected } where selected = 'sci-fi'.
Common situations: Single-select UIs producing one value where the filter template expects a list; API params accepting both scalar and array forms; copy-pasting $eq syntax into $in.
Related errors
- Expected where to be a non-empty object
- Expected 'where' to have exactly one operator, but got ${Obj
- Expected 'where' value to be a string, number, boolean, or a
- Expected 'where' value for $and or $or to be a list of 'wher
- Expected operator expression to have one operator, but got $
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/28bbbdf43896908d.
Report an issue: GitHub.