{"record":{"id":"f82efd1696f1efcd","repo":"chroma-core/chroma","slug":"regex-requires-a-string-pattern","errorCode":null,"errorMessage":"$regex requires a string pattern","messagePattern":"\\$regex requires a string pattern","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"clients/new-js/packages/chromadb/src/execution/expression/key.ts","lineNumber":86,"sourceCode":"   * Not-contains filter.\n   *\n   * On `Key.DOCUMENT`: excludes documents containing the substring.\n   * On metadata fields: checks that the array field does not contain the scalar value.\n   *\n   * @example\n   * K.DOCUMENT.notContains(\"deprecated\")   // document substring exclusion\n   * K(\"tags\").notContains(\"draft\")          // metadata array not-contains\n   */\n  public notContains(value: string | number | boolean): WhereExpression {\n    if (this.name === \"#document\" && typeof value !== \"string\") {\n      throw new TypeError(\"K.DOCUMENT.notContains requires a string value\");\n    }\n    return createComparisonWhere(this.name, \"$not_contains\", value);\n  }\n\n  public regex(pattern: string): WhereExpression {\n    if (typeof pattern !== \"string\") {\n      throw new TypeError(\"$regex requires a string pattern\");\n    }\n    return createComparisonWhere(this.name, \"$regex\", pattern);\n  }\n\n  public notRegex(pattern: string): WhereExpression {\n    if (typeof pattern !== \"string\") {\n      throw new TypeError(\"$not_regex requires a string pattern\");\n    }\n    return createComparisonWhere(this.name, \"$not_regex\", pattern);\n  }\n}\n\nexport interface KeyFactory {\n  (name: string): Key;\n  ID: Key;\n  DOCUMENT: Key;\n  EMBEDDING: Key;\n  METADATA: Key;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/new-js/packages/chromadb/src/execution/expression/key.ts#L68-L104","documentation":"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.","triggerScenarios":"K(\"title\").regex(new RegExp(\"^How\")).regex(42), or .regex(null) when an optional pattern config is unset.","commonSituations":"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.","solutions":["Pass the pattern as a string: K(\"title\").regex(\"^How\")","If you hold a RegExp, pass its source: K(\"title\").regex(re.source)","Guard optional patterns: only call .regex(p) when typeof p === \"string\""],"exampleFix":"// before\nK(\"title\").regex(new RegExp(\"^How\")); // RegExp object -> TypeError\n\n// after\nK(\"title\").regex(\"^How\"); // or re.source for an existing RegExp","handlingStrategy":"validation","validationCode":"const pattern = typeof input === \"string\" ? input : (input as RegExp)?.source;\nif (typeof pattern !== \"string\" || pattern.length === 0) {\n  throw new Error(\"Provide the regex as a pattern string\");\n}\nK(\"title\").regex(pattern);","typeGuard":"const isPatternString = (v: unknown): v is string => typeof v === \"string\" && v.length > 0;","tryCatchPattern":null,"preventionTips":["The API takes the pattern STRING, not a RegExp — pass re.source when you have one","Guard optional config patterns with typeof checks before calling .regex()","Validate config-driven patterns at startup, not at query time"],"tags":["chroma","where-filter","regex","typeerror"],"backgroundTag":"wrong-argument-type","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}