different-ai/openwork · error · InterpreterRuntimeError
String.${method} received the string ${JSON.stringify(arg)},
Error message
String.${method} received the string ${JSON.stringify(arg)}, which is not a valid regular expression pattern (${regexFailureReason(error)}). ${escapeRegexHint} What it means
toHostRegex compiles string arguments into host RegExp for String methods like match/replace/split. When the pattern string fails to compile (invalid syntax such as unbalanced brackets or bad groups), the underlying SyntaxError is rethrown as this InterpreterRuntimeError — surfaced as a SyntaxError via .as() — including the original failure reason and a hint about escaping.
Source
Thrown at packages/codemode/src/stdlib/regexp.ts:27
"multiline",
"sticky",
"unicode",
"dotAll",
])
export const regexFailureReason = (error: unknown): string =>
(error instanceof Error ? error.message : String(error)).replace(/^Invalid regular expression:\s*/i, "")
export const escapeRegexHint =
'To match special characters like ( ) [ ] { } + * ? . literally, escape them with a backslash (e.g. "\\\\(") or test for them with String.includes instead.'
export const toHostRegex = (arg: unknown, method: string, node: AstNode, extraFlags = ""): RegExp => {
if (arg instanceof SandboxRegExp) return arg.regex
if (typeof arg === "string") {
try {
return new RegExp(arg, extraFlags)
} catch (error) {
throw new InterpreterRuntimeError(
`String.${method} received the string ${JSON.stringify(arg)}, which is not a valid regular expression pattern (${regexFailureReason(error)}). ${escapeRegexHint}`,
node,
).as("SyntaxError")
}
}
throw new InterpreterRuntimeError(
`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`,
node,
)
}
export const matchToValue = (match: RegExpMatchArray): Array<unknown> => {
const result: Array<unknown> = Array.from(match, (group) => group)
if (match.index !== undefined) (result as Record<string, unknown> & Array<unknown>).index = match.index
if (match.groups) {
const groups: SafeObject = Object.create(null) as SafeObject
for (const [key, group] of Object.entries(match.groups)) {
if (!isBlockedMember(key)) groups[key] = groupView on GitHub (pinned to 2b7df46e8a)
Solutions
- Escape dynamic input before embedding: use an escapeRegExp helper (replace /[.*+?^${}()|[\]\\]/g, '\\$&')
- Validate the pattern compiles in a plain JS try/catch with new RegExp(pattern) before running the CodeMode script
- Prefer literal strings with split/indexOf over regex when the pattern is data
- Fix hand-written regex syntax (balanced brackets, valid quantifiers) — the message names the exact failure reason
Example fix
// before
const parts = text.match('(' + userDelimiter + ')')
// after
const esc = userDelimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const parts = text.match('(' + esc + ')') Defensive patterns
Strategy: try-catch
Validate before calling
function isValidRegex(pattern: string): boolean {
try { new RegExp(pattern); return true } catch { return false }
}
if (!isValidRegex(pattern)) pattern = escapeRegExp(pattern) Try / catch
try {
return text.match(pattern)
} catch (e) {
if (e instanceof InterpreterRuntimeError && e.message.includes('not a valid regular expression pattern')) {
return text.split(escapeRegExp(pattern))[0] // or literal fallback
}
throw e
} Prevention
- Escape dynamic input with an escapeRegExp helper before embedding
- Precompile/validate patterns with new RegExp(pattern) in a plain try/catch before scripting
- Prefer string split/indexOf over regex when the pattern is data
- Check the failure reason in the message — it names the exact syntax problem
When it happens
Trigger: String.match('['), String.replaceAll('a{2,1}', ...), patterns interpolated from user input like new RegExp('(' + userTag + ')') where userTag contains regex metacharacters, unescaped dots/brackets from data, or an empty/invalid group '()+' edge in dynamically built patterns.
Common situations: Building patterns from config values or user-supplied delimiters without escaping; log-parsing scripts where the delimiter contains regex specials like '(' or '['; LLM-generated code with hand-written regex typos.
Related errors
- String.replaceAll requires a regular expression with the glo
- String.matchAll requires a regular expression with the globa
- JSON.parse received invalid JSON: ${error instanceof Error ?
- String.${method} expects a regular expression (a /pattern/fl
- RegExp method '${name}' is not available in CodeMode.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/ea867e024de6089c.
Report an issue: GitHub.