{"record":{"id":"6bf94c1c1190a873","repo":"different-ai/openwork","slug":"string-matchall-requires-a-regular-expression-with","errorCode":null,"errorMessage":"String.matchAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.match for a single match.","messagePattern":"String\\.matchAll requires a regular expression with the global \\(g\\) flag: write /(.+?)/(.+?)g, or use String\\.match for a single match\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/interpreter/runtime.ts","lineNumber":453,"sourceCode":"        result = value.replace(str(0), str(1))\n        break\n      }\n      result = value.replaceAll(str(0), str(1))\n      break\n    }\n    case \"match\": {\n      const pattern = toHostRegex(args[0], name, node)\n      const matched = value.match(pattern)\n      if (matched === null) return null\n      // A global match is a plain array of matched strings; a non-global match carries\n      // index/groups own properties, so bypass the copying data checkpoint to keep them.\n      if (pattern.global) return boundedData(matched, \"String.match result\")\n      return matchToValue(matched)\n    }\n    case \"matchAll\": {\n      const pattern = toHostRegex(args[0], name, node, \"g\")\n      if (!pattern.global) {\n        throw new InterpreterRuntimeError(\n          `String.matchAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.match for a single match.`,\n          node,\n        )\n      }\n      // Materialized as an array (not an iterator); each entry is a match array with\n      // index/groups own properties. Match count is bounded by the subject length.\n      return Array.from(value.matchAll(pattern), matchToValue)\n    }\n    case \"search\": {\n      result = value.search(toHostRegex(args[0], name, node))\n      break\n    }\n    case \"repeat\": {\n      const count = num(0)\n      if (!Number.isFinite(count) || count < 0)\n        throw new InterpreterRuntimeError(\"String.repeat expects a finite non-negative count.\", node)\n      result = value.repeat(count)\n      break","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/interpreter/runtime.ts#L435-L471","documentation":"String.matchAll requires a global regex; the host JS spec also throws a TypeError for non-global patterns here. The sandbox validates pattern.global after converting the argument via toHostRegex and throws with a message showing the fixed literal (flags + g) and suggesting String.match for a single match. Note this check only fires for patterns that survived toHostRegex without already erroring; the result is materialized as an array, not an iterator.","triggerScenarios":"Calling str.matchAll(/ab/) without g; passing a regex built via new RegExp(src) with no flags; reusing a non-global regex shared with String.match or String.search; passing a string argument that toHostRegex converted into a non-global regex.","commonSituations":"Porting host code that iterated matchAll with a non-global regex and relied on the TypeError; generating regexes from user config where flags are omitted; switching from match to matchAll without adding the flag.","solutions":["Add the g flag: str.matchAll(/ab/g)","Include 'g' when constructing dynamically: new RegExp(source, \"g\")","Use String.match(pattern) instead if only the first match is needed","For string search values, wrap them with an explicit global regex"],"exampleFix":"// before\nfor (const m of text.matchAll(/(\\w+)=(\\w+)/)) { ... }\n// after\nfor (const m of text.matchAll(/(\\w+)=(\\w+)/g)) { ... }","handlingStrategy":"type-guard","validationCode":"if (!(re instanceof RegExp && re.global)) throw new TypeError(\"matchAll needs a /g regex\")\nconst matches = text.matchAll(re)","typeGuard":"const isGlobalRegex = (v) => v instanceof RegExp && v.global","tryCatchPattern":"try { out = [...text.matchAll(re)] } catch (e) { if (String(e.message).includes(\"global (g) flag\")) out = text.match(re) !== null ? [text.match(re)] : []; else throw e }","preventionTips":["Never pass a regex without g to matchAll","Keep separate regex constants for match (single) vs matchAll (global)","Reset lastIndex concerns by using fresh global regexes per loop","Materialize the array (sandbox returns an array, not an iterator)"],"tags":["codemode","interpreter","regex","string-methods","matchall"],"backgroundTag":"regex-missing-global-flag","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}