chroma-core/chroma · error · Error

Unsupported where operator: ${operator}

Error message

Unsupported where operator: ${operator}

What it means

The parser resolves each operator key against a fixed map that supports exactly: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $contains, $not_contains, $regex and $not_regex. Any other operator string inside an operator dictionary throws this error client-side. Notably there is no $between, $like, $exists or $size.

Source

Thrown at clients/new-js/packages/chromadb/src/execution/expression/where.ts:231

    throw new Error("Where dictionary must contain exactly one field");
  }

  const [field, value] = entries[0];
  if (!isPlainObject(value)) {
    return new ComparisonWhere(field, "$eq", value);
  }

  const operatorEntries = Object.entries(value);
  if (operatorEntries.length !== 1) {
    throw new Error(
      `Operator dictionary for field "${field}" must contain exactly one operator`,
    );
  }

  const [operator, operand] = operatorEntries[0];
  const factory = comparisonOperatorMap.get(operator);
  if (!factory) {
    throw new Error(`Unsupported where operator: ${operator}`);
  }

  return factory(field, operand);
};

export const createComparisonWhere = (
  key: string,
  operator: string,
  value: unknown,
): WhereExpression => new ComparisonWhere(key, operator, value);

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Replace $between with { $and: [{ f: { $gte: min } }, { f: { $lte: max } }] }.
  2. Replace $like with $contains (substring) or $regex (pattern).
  3. Drop $exists — model optional metadata explicitly or filter client-side.
  4. Check spelling and case against the supported list: $eq $ne $gt $gte $lt $lte $in $nin $contains $not_contains $regex $not_regex.

Example fix

// before
where: { title: { $like: 'report' } }

// after
where: { title: { $contains: 'report' } }
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED_OPERATORS = new Set([
  '$eq', '$ne', '$gt', '$gte', '$lt', '$lte',
  '$in', '$nin', '$contains', '$not_contains', '$regex', '$not_regex',
]);
function assertSupportedOperators(where: Record<string, unknown>): void {
  for (const [k, v] of Object.entries(where)) {
    if (k === '$and' || k === '$or') {
      (v as unknown[]).forEach((c) => assertSupportedOperators(c as Record<string, unknown>));
      continue;
    }
    if (v && typeof v === 'object' && !Array.isArray(v)) {
      for (const op of Object.keys(v)) {
        if (!SUPPORTED_OPERATORS.has(op)) {
          throw new Error(`Unsupported operator ${op} on field ${k}`);
        }
      }
    }
  }
}

Type guard

function isSupportedOperator(op: string): boolean {
  return [
    '$eq', '$ne', '$gt', '$gte', '$lt', '$lte',
    '$in', '$nin', '$contains', '$not_contains', '$regex', '$not_regex',
  ].includes(op);
}

Try / catch

try {
  await collection.query({ where });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Unsupported where operator')) {
    // rewrite the clause ($between -> $and range, $like -> $contains) and retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: where: { price: { $between: [10, 100] } }; Mongo-isms like { title: { $like: '%report%' } } or { tags: { $exists: true } }; casing or spelling typos like $GTE, $greter, $Contain.

Common situations: Translating MongoDB or SQL WHERE syntax to Chroma; using an operator added in a newer Chroma server version that this client's parser does not know; hand-typing operator strings without a shared constant.

Related errors


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