{"record":{"id":"3bd0c4ded124cdf0","repo":"gatsbyjs/gatsby","slug":"the-regex-comparator-is-expecting-the-regex-as-a","errorCode":null,"errorMessage":"The $regex comparator is expecting the regex as a string, not an actual regex or anything else","messagePattern":"The \\$regex comparator is expecting the regex as a string, not an actual regex or anything else","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby/src/datastore/common/query.ts","lineNumber":190,"sourceCode":" *\n * Example:\n *   { foo: { eq: 5 } } -> { foo: { $eq: 5 }}\n */\nexport function prepareQueryArgs(\n  filterFields: Array<IInputQuery> | IInputQuery = {}\n): IPreparedQueryArg {\n  const filters = {}\n  Object.keys(filterFields).forEach(key => {\n    const value = filterFields[key]\n    if (_.isPlainObject(value)) {\n      filters[key === `elemMatch` ? `$elemMatch` : key] = prepareQueryArgs(\n        value as IInputQuery\n      )\n    } else {\n      switch (key) {\n        case `regex`:\n          if (typeof value !== `string`) {\n            throw new Error(\n              `The $regex comparator is expecting the regex as a string, not an actual regex or anything else`\n            )\n          }\n          filters[`$regex`] = prepareRegex(value)\n          break\n        case `glob`:\n          filters[`$regex`] = makeRe(value)\n          break\n        default:\n          filters[`$${key}`] = value\n      }\n    }\n  })\n  return filters\n}\n\n// Converts a nested mongo args object into a dotted notation. acc\n// (accumulator) must be a reference to an empty object. The converted","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/datastore/common/query.ts#L172-L208","documentation":"Gatsby's GraphQL `filter: { field: { regex: ... } }` operator expects the pattern as a string (Gatsby then compiles it to a `RegExp` via `prepareRegex`). Passing an actual `RegExp` object, a number, or any non-string is rejected because the value must be JSON-serialisable and transport-stable.","triggerScenarios":"Query like `allMarkdownRemark(filter: { frontmatter: { title: { regex: /foo/i } } })` (a literal regex object) or a programmatic query that injects an `RegExp`.","commonSituations":"Writing filter values in source that look like JS regex literals; passing variables whose value is a `RegExp`; migrating from a client library that accepts `RegExp`.","solutions":["Provide the pattern as a string, e.g. `regex: \"/foo/i\"`.","Put flags inside the string (leading `/.../flags`) per Gatsby's `prepareRegex` convention.","If building queries programmatically, ensure the value is `String(pattern)`."],"exampleFix":"// before\nallX(filter: { title: { regex: /foo/i } })\n// after\nallX(filter: { title: { regex: \"/foo/i\" } })","handlingStrategy":"type-guard","validationCode":"// Before building the query string, coerce regex filter values.\nfunction normalizeRegexFilter(value) {\n  if (value instanceof RegExp) return value.toString() // \"/pat/flags\"\n  if (typeof value !== \"string\") throw new Error(\"regex filter must be a string\")\n  return value\n}\n","typeGuard":"function isRegexFilterValue(v: unknown): v is string {\n  return typeof v === \"string\"\n}\n","tryCatchPattern":null,"preventionTips":["Always quote regex patterns as strings in queries.","Type GraphQL variables used for regex as `String!`, never a custom scalar that wraps RegExp."],"tags":["graphql","query","filter","regex","datastore"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}