chroma-core/chroma · error · TypeError

$regex requires a string pattern

Error message

$regex requires a string pattern

What it means

Key.regex(pattern) builds a $regex where-filter and validates at runtime that the pattern is a string. Passing anything else — most commonly a RegExp object, but also a number or null (from untyped JS callers or any-typed values) — raises a TypeError before the filter is created.

Source

Thrown at clients/new-js/packages/chromadb/src/execution/expression/key.ts:86

   * Not-contains filter.
   *
   * On `Key.DOCUMENT`: excludes documents containing the substring.
   * On metadata fields: checks that the array field does not contain the scalar value.
   *
   * @example
   * K.DOCUMENT.notContains("deprecated")   // document substring exclusion
   * K("tags").notContains("draft")          // metadata array not-contains
   */
  public notContains(value: string | number | boolean): WhereExpression {
    if (this.name === "#document" && typeof value !== "string") {
      throw new TypeError("K.DOCUMENT.notContains requires a string value");
    }
    return createComparisonWhere(this.name, "$not_contains", value);
  }

  public regex(pattern: string): WhereExpression {
    if (typeof pattern !== "string") {
      throw new TypeError("$regex requires a string pattern");
    }
    return createComparisonWhere(this.name, "$regex", pattern);
  }

  public notRegex(pattern: string): WhereExpression {
    if (typeof pattern !== "string") {
      throw new TypeError("$not_regex requires a string pattern");
    }
    return createComparisonWhere(this.name, "$not_regex", pattern);
  }
}

export interface KeyFactory {
  (name: string): Key;
  ID: Key;
  DOCUMENT: Key;
  EMBEDDING: Key;
  METADATA: Key;

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass the pattern as a string: K("title").regex("^How")
  2. If you hold a RegExp, pass its source: K("title").regex(re.source)
  3. Guard optional patterns: only call .regex(p) when typeof p === "string"

Example fix

// before
K("title").regex(new RegExp("^How")); // RegExp object -> TypeError

// after
K("title").regex("^How"); // or re.source for an existing RegExp
Defensive patterns

Strategy: validation

Validate before calling

const pattern = typeof input === "string" ? input : (input as RegExp)?.source;
if (typeof pattern !== "string" || pattern.length === 0) {
  throw new Error("Provide the regex as a pattern string");
}
K("title").regex(pattern);

Type guard

const isPatternString = (v: unknown): v is string => typeof v === "string" && v.length > 0;

Prevention

When it happens

Trigger: K("title").regex(new RegExp("^How")).regex(42), or .regex(null) when an optional pattern config is unset.

Common situations: The most frequent mistake is passing a RegExp instance — the API takes the pattern STRING, not a compiled RegExp (use regexObj.source). Also: patterns loaded from config that are undefined/nullable, and TS callers bypassing the string signature via any.

Related errors


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