can1357/oh-my-pi · error · OmpTypeError
invalid regular expression "${src.slice(i, end)}"
Error message
invalid regular expression "${src.slice(i, end)}" What it means
A properly delimited regex literal `/.../flags` was tokenized, but `new RegExp(source, flags)` threw — the pattern or its flags are syntactically invalid JavaScript. The tokenizer rethrows as `OmpTypeError` including the literal text.
Source
Thrown at packages/omptype/src/ir.ts:234
toks.push({ t: "str", v: value });
i = j + 1;
continue;
}
if (c === "/") {
let j = i + 1;
for (; j < n; j++) {
if (src[j] === "\\") j++;
else if (src[j] === "/") break;
}
if (j >= n) throw new OmpTypeError(`unterminated regular expression in "${src}"`);
let end = j + 1;
while (end < n && /[dgimsuvy]/.test(src[end])) end++;
const source = src.slice(i + 1, j);
const flags = src.slice(j + 1, end);
try {
toks.push({ t: "regex", v: new RegExp(source, flags) });
} catch {
throw new OmpTypeError(`invalid regular expression "${src.slice(i, end)}"`);
}
i = end;
continue;
}
if ((c >= "0" && c <= "9") || (c === "-" && i + 1 < n && src[i + 1] >= "0" && src[i + 1] <= "9")) {
let j = i + 1;
while (j < n && /[\w.+-]/.test(src[j])) j++;
const raw = src.slice(i, j);
if (/^-?(?:0|[1-9]\d*)n$/.test(raw) && raw !== "-0n") {
toks.push({ t: "bigint", v: BigInt(raw.slice(0, -1)) });
} else {
const valid =
/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(raw) && !Object.is(Number(raw), -0) && String(Number(raw)) === raw;
if (!valid) throw new OmpTypeError(`Malformed number literal '${raw}'`);
toks.push({ t: "num", v: Number(raw) });
}
i = j;
continue;View on GitHub (pinned to 9690622007)
Solutions
- Test the pattern with `new RegExp(p, flags)` in a REPL to see the underlying SyntaxError.
- Remove invalid/duplicate flags; valid flags are d,g,i,m,s,u,v,y.
- Replace engine-unsupported constructs (e.g. `(?R)`, `\K`) with JS-compatible equivalents.
- Pre-validate the regex with a try/catch around `new RegExp` before embedding it in the expression.
Example fix
// before type(`value ~= /[a-z+/`); // unbalanced class // after type(`value ~= /[a-z]+/`);
Defensive patterns
Strategy: validation
Validate before calling
function assertValidRegex(pattern: string, flags: string): void {
try { new RegExp(pattern, flags); } catch (e) {
throw new Error(`Invalid regex /${pattern}/${flags}: ${(e as Error).message}`);
}
} Try / catch
try {
const t = new TypeExpression(src);
} catch (err) {
if (err instanceof Error && err.message.startsWith("invalid regular expression")) {
throw new Error(`Fix pattern syntax: ${err.message}`);
}
throw err;
} Prevention
- Test every pattern with `new RegExp` before embedding it in an expression.
- Use only flags d,g,i,m,s,u,v,y without duplicates.
- Avoid non-JS regex flavors (PCRE/RE2-only constructs); keep the `u` flag in mind for escape rules.
When it happens
Trigger: Malformed patterns like `/(/` (unclosed group), `/[a-/`, `/(?<name/x)/` (invalid group), or invalid flag combos like `/x/yy` (duplicate flag).
Common situations: Regexes authored for another flavor (PCRE/RE2 constructs like lookbehind variants unsupported by the JS engine version); duplicated or typo'd flags; hand-edited patterns with unbalanced brackets.
Related errors
- unterminated regular expression in "${src}"
- err.to_string() (invalid regex pattern)
- invalid regular expression: {0}
- No files were modified.
- The first line of the patch must be '*** Begin Patch'
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b5edc89321ec89b2.
Report an issue: GitHub.