chroma-core/chroma · error · TypeError

$or must be a non-empty array

Error message

$or must be a non-empty array

What it means

The Chroma JS client compiles every `where` filter into a WhereExpression tree before serializing it to the server. When a filter dictionary uses the `$or` key, its value must be an array containing at least one nested where clause (the same rule applies to `$and`). This TypeError is thrown client-side at parse time when the `$or` value is not an array at all, or is an empty array, so no network request is ever made.

Source

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

    });
    if (conditions.length === 1) {
      return conditions[0];
    }
    return conditions
      .slice(1)
      .reduce(
        (acc, condition) => AndWhere.combine(acc, condition),
        conditions[0],
      );
  }

  if ("$or" in data) {
    if (Object.keys(data).length !== 1) {
      throw new Error("$or cannot be combined with other keys");
    }
    const rawConditions = data["$or"];
    if (!Array.isArray(rawConditions) || rawConditions.length === 0) {
      throw new TypeError("$or must be a non-empty array");
    }
    const conditions = rawConditions.map((item, index) => {
      const expr = WhereExpression.from(item as WhereInput);
      if (!expr) {
        throw new TypeError(`Invalid where clause at index ${index}`);
      }
      return expr;
    });
    if (conditions.length === 1) {
      return conditions[0];
    }
    return conditions
      .slice(1)
      .reduce(
        (acc, condition) => OrWhere.combine(acc, condition),
        conditions[0],
      );
  }

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. If the dynamic condition list can be empty, omit the filter entirely: pass where: undefined (or leave the property out) when the list has zero clauses.
  2. If only one condition remains, pass it directly instead of wrapping: where: clauses[0], not { $or: [clauses[0]] } or { $or: clauses[0] }.
  3. Make sure the $or value is an array of clause objects: { $or: [{ status: 'active' }, { status: 'pending' }] }.
  4. If you meant a logical AND, use { $and: [...] } with the same non-empty-array rule.

Example fix

// before
const where = { $or: clauses }; // clauses may be [] -> TypeError
await collection.query({ queryTexts: ['x'], where });

// after
const where = clauses.length === 0 ? undefined :
  clauses.length === 1 ? clauses[0] : { $or: clauses };
await collection.query({ queryTexts: ['x'], where });
Defensive patterns

Strategy: validation

Validate before calling

function buildOr(clauses: unknown[]): Record<string, unknown> | undefined {
  const valid = clauses.filter((c) => c !== null && c !== undefined);
  if (valid.length === 0) return undefined; // omit the filter entirely
  if (valid.length === 1) return valid[0] as Record<string, unknown>;
  return { $or: valid };
}

Type guard

function isValidOrWhere(where: unknown): boolean {
  if (typeof where !== 'object' || where === null) return true;
  if ('$or' in where) {
    const v = (where as Record<string, unknown>).$or;
    return Array.isArray(v) && v.length > 0;
  }
  return true;
}

Try / catch

try {
  await collection.query({ queryTexts, where });
} catch (e) {
  if (e instanceof TypeError && e.message.includes('$or')) {
    // rebuild the filter without the empty $or and retry
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling collection.query with where: { $or: [] }; passing a single object instead of an array, e.g. where: { $or: { status: 'active' } }; building the $or list at runtime from a source array that happens to be empty (e.g. items.map(...).filter(...) with no matches).

Common situations: Dynamically composed filters where the OR branch is optional and sometimes empty; porting MongoDB/SQL OR syntax that permits an object shorthand or an empty disjunction; spreading user-supplied filter parts into { $or: parts } without checking parts.length.

Related errors


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