different-ai/openwork · error · InterpreterRuntimeError
String.matchAll requires a regular expression with the globa
Error message
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. What it means
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.
Source
Thrown at packages/codemode/src/interpreter/runtime.ts:453
result = value.replace(str(0), str(1))
break
}
result = value.replaceAll(str(0), str(1))
break
}
case "match": {
const pattern = toHostRegex(args[0], name, node)
const matched = value.match(pattern)
if (matched === null) return null
// A global match is a plain array of matched strings; a non-global match carries
// index/groups own properties, so bypass the copying data checkpoint to keep them.
if (pattern.global) return boundedData(matched, "String.match result")
return matchToValue(matched)
}
case "matchAll": {
const pattern = toHostRegex(args[0], name, node, "g")
if (!pattern.global) {
throw new InterpreterRuntimeError(
`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.`,
node,
)
}
// Materialized as an array (not an iterator); each entry is a match array with
// index/groups own properties. Match count is bounded by the subject length.
return Array.from(value.matchAll(pattern), matchToValue)
}
case "search": {
result = value.search(toHostRegex(args[0], name, node))
break
}
case "repeat": {
const count = num(0)
if (!Number.isFinite(count) || count < 0)
throw new InterpreterRuntimeError("String.repeat expects a finite non-negative count.", node)
result = value.repeat(count)
breakView on GitHub (pinned to 2b7df46e8a)
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
Example fix
// before
for (const m of text.matchAll(/(\w+)=(\w+)/)) { ... }
// after
for (const m of text.matchAll(/(\w+)=(\w+)/g)) { ... } Defensive patterns
Strategy: type-guard
Validate before calling
if (!(re instanceof RegExp && re.global)) throw new TypeError("matchAll needs a /g regex")
const matches = text.matchAll(re) Type guard
const isGlobalRegex = (v) => v instanceof RegExp && v.global
Try / catch
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 } Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- String.replaceAll requires a regular expression with the glo
- String.${name} expects argument ${index + 1} to be a number.
- String.normalize expects the form "NFC", "NFD", "NFKC", or "
- String.repeat expects a finite non-negative count.
- Expected '${key}' to be a boolean.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/6bf94c1c1190a873.
Report an issue: GitHub.