{"record":{"id":"77be2730987b6c35","repo":"can1357/oh-my-pi","slug":"invalid-regular-expression-pattern-json-stringif","errorCode":null,"errorMessage":"invalid regular expression pattern ${JSON.stringify(opts.pattern)}","messagePattern":"invalid regular expression pattern (.+?)","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/typebox.ts","lineNumber":214,"sourceCode":"\treturn schema;\n}\n\nfunction checkFiniteOption(name: string, value: number | undefined): void {\n\tif (value !== undefined && !Number.isFinite(value)) throw new OmpTypeError(`${name} must be finite`);\n}\n\nfunction tString(opts?: StringOpts): TString {\n\tcheckFiniteOption(\"minLength\", opts?.minLength);\n\tcheckFiniteOption(\"maxLength\", opts?.maxLength);\n\tlet schema = asRuntime<string>(type.raw(opts?.format === \"url\" || opts?.format === \"uri\" ? \"string.url\" : \"string\"));\n\tif (opts?.minLength !== undefined) schema = schema.atLeastLength(opts.minLength);\n\tif (opts?.maxLength !== undefined) schema = schema.atMostLength(opts.maxLength);\n\tif (opts?.pattern !== undefined) {\n\t\tlet regex: RegExp;\n\t\ttry {\n\t\t\tregex = new RegExp(opts.pattern);\n\t\t} catch {\n\t\t\tthrow new OmpTypeError(`invalid regular expression pattern ${JSON.stringify(opts.pattern)}`);\n\t\t}\n\t\tschema = schema.narrow((value, ctx) => regex.test(value) || ctx.mustBe(`a string matching ${opts.pattern}`));\n\t}\n\tif (opts?.format !== undefined && opts.format !== \"url\" && opts.format !== \"uri\") {\n\t\tconst format = opts.format;\n\t\tconst valid = formatPredicate(format);\n\t\tschema = schema.narrow((value, ctx) => valid(value) || ctx.mustBe(`a string in ${format} format`));\n\t}\n\tconst result = applyMeta(schema, opts);\n\tconst keywords: Record<string, unknown> = {};\n\tif (opts?.pattern !== undefined) keywords.pattern = opts.pattern;\n\tif (opts?.format !== undefined) keywords.format = opts.format === \"url\" ? \"uri\" : opts.format;\n\treturn opts?.pattern !== undefined || opts?.format !== undefined ? withJsonSchemaKeywords(result, keywords) : result;\n}\n\nfunction formatPredicate(format: string): (value: string) => boolean {\n\tswitch (format) {\n\t\tcase \"url\":","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/typebox.ts#L196-L232","documentation":"When `tString` receives a `pattern` option it compiles it with `new RegExp(pattern)`. If the pattern is syntactically invalid (unbalanced parens, bad flags-embedded constructs, invalid quantifiers), the engine's throw is caught and rethrown as `invalid regular expression pattern <JSON>`.","triggerScenarios":"`tString({ pattern: \"(\" })`, `tString({ pattern: \"a{2,1}\" })`, or any user-supplied regex string from config/CLI/API that is not a valid JS RegExp.","commonSituations":"Letting end users supply regex filters through config files or API payloads; regexes copied from other tools (e.g. sed/grep syntax, PCRE) that are invalid in JS; double-escaping mistakes when building patterns from strings (`\"\\\\d\"` vs `\"\\d\"` in non-raw contexts).","solutions":["Fix the pattern so it is valid JavaScript RegExp syntax — test it in the console with `new RegExp(pattern)`.","Pre-validate user-supplied patterns with try { new RegExp(p) } before passing them to tString and surface a friendly config error.","Convert non-JS regex syntax (lookbehind differences, POSIX classes, `\\p{...}` without the u flag) to JS-compatible equivalents."],"exampleFix":"// before\ntString({ pattern: config.regex }); // throws if config.regex is \"(\"\n// after\nlet re;\ntry { re = new RegExp(config.regex); } catch { throw new Error(`config.regex is not a valid pattern: ${config.regex}`); }\ntString({ pattern: config.regex });","handlingStrategy":"validation","validationCode":"function assertValidPattern(p: string): string {\n  try { new RegExp(p); return p; }\n  catch { throw new Error(`Not a valid JS RegExp: ${JSON.stringify(p)}`); }\n}\n// use: tString({ pattern: assertValidPattern(config.regex) })","typeGuard":"function isValidRegex(p: string): boolean {\n  try { new RegExp(p); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  const s = tString({ pattern: userPattern });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('invalid regular expression pattern')) {\n    throw new ConfigError(`Invalid regex in config: ${JSON.stringify(userPattern)}`);\n  }\n  throw err;\n}","preventionTips":["Pre-validate any user/config-supplied regex with new RegExp before it reaches the schema.","Convert patterns from other dialects (PCRE/grep) to JS syntax explicitly.","Beware string-escaping: prefer template/raw sources so `\\d` isn't collapsed before compilation."],"tags":["omptype","regex","schema-construction","invalid-argument"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}