chroma-core/chroma · error · ChromaValueError

Expected 'where' operand value to be a non-empty list and al

Error message

Expected 'where' operand value to be a non-empty list and all values to be of the same type

What it means

Array operands in where operator expressions must be non-empty and type-homogeneous — the same rule as metadata lists. An empty $in list ({$in: []}) or a mixed list ({$in: [1, 'a']}) throws ChromaValueError client-side. Homogeneity is checked against typeof of the first element.

Source

Thrown at clients/new-js/packages/chromadb/src/utils.ts:636

          `Expected operator to be one of $gt, $gte, $lt, $lte, $ne, $eq, $in, $nin, $contains, $not_contains, but got ${operator}`,
        );
      }

      if (
        !["string", "number", "boolean"].includes(typeof operand) &&
        !Array.isArray(operand)
      ) {
        throw new ChromaValueError(
          "Expected operand value to be a string, number, boolean, or a list of those types",
        );
      }

      if (
        Array.isArray(operand) &&
        (operand.length === 0 ||
          !operand.every((item) => typeof item === typeof operand[0]))
      ) {
        throw new ChromaValueError(
          "Expected 'where' operand value to be a non-empty list and all values to be of the same type",
        );
      }
    }
  });
};

/**
 * Validates a where document clause for document content filtering.
 * @param whereDocument - Where document clause to validate
 * @throws ChromaValueError if the clause is malformed
 */
export const validateWhereDocument = (whereDocument: WhereDocument) => {
  if (typeof whereDocument !== "object") {
    throw new ChromaValueError(
      "Expected 'whereDocument' to be a non-empty object",
    );
  }

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Skip the filter (or the query) when the list is empty.
  2. Normalize element types: list.map(Number) or list.map(String).
  3. Check non-empty and uniform typeof before issuing the query.

Example fix

// before
const where = { genre: { $in: selected } }; // selected = []

// after
const where = selected.length ? { genre: { $in: selected } } : undefined;
Defensive patterns

Strategy: validation

Validate before calling

const cleanIn = (field, list) => list.length && list.every(v => typeof v === typeof list[0])
  ? { [field]: { $in: list } }
  : undefined;
const where = cleanIn('genre', selected) ?? {}; // omit filter when invalid/empty

Type guard

const isUniformList = (v: unknown): v is [unknown, ...unknown[]] =>
  Array.isArray(v) && v.length > 0 && v.every(item => typeof item === typeof v[0]);

Try / catch

try {
  await collection.query({ queryTexts, where });
} catch (e) {
  if ((e as Error).message.includes('non-empty list and all values')) {
    // drop the empty list or coerce mixed types to one type, then retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: where: { genre: { $in: [] } } — empty selection from a faceted UI. { $in: ['1', 2] } — query-param values partially converted to numbers.

Common situations: Multi-select widgets where the user selects nothing; merging typed and stringified values; a default empty list reaching the query unchecked.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/7a231a28ebb0832e. Report an issue: GitHub.