{"record":{"id":"a1e9e5fd9332bcc5","repo":"ory/kratos","slug":"identity-schema-rejected-invalid-regex-in-pattern","errorCode":null,"errorMessage":"identity schema rejected: invalid regex in pattern: %w","messagePattern":"identity schema rejected: invalid regex in pattern: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/prevalidate.go","lineNumber":87,"sourceCode":"\t\t// Record `$ref` for cycle detection in detectRefCycles. Root\n\t\t// pointers (`#`, `#/`, empty) map to the empty path. Anything\n\t\t// without a `#/` prefix is external — out of scope here;\n\t\t// loadRefURL handles scheme enforcement.\n\t\tif ref, ok := v[\"$ref\"].(string); ok {\n\t\t\tswitch {\n\t\t\tcase ref == \"\" || ref == \"#\" || ref == \"#/\":\n\t\t\t\tp.refs[path] = \"\"\n\t\t\tcase strings.HasPrefix(ref, \"#/\"):\n\t\t\t\tp.refs[path] = strings.TrimPrefix(ref, \"#\")\n\t\t\t}\n\t\t}\n\n\t\t// Pre-compile `pattern` regexes so an invalid one returns a\n\t\t// kratos-side error instead of panicking deep in\n\t\t// regexp.MustCompile during the upstream compile.\n\t\tif pat, ok := v[\"pattern\"].(string); ok {\n\t\t\tif _, err := regexp.Compile(pat); err != nil {\n\t\t\t\treturn fmt.Errorf(\"identity schema rejected: invalid regex in pattern: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\t// patternProperties keys are themselves regexes.\n\t\tif patternProps, ok := v[\"patternProperties\"].(map[string]any); ok {\n\t\t\tfor raw := range patternProps {\n\t\t\t\tif _, err := regexp.Compile(raw); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"identity schema rejected: invalid regex in patternProperties key %q: %w\", raw, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor k, sub := range v {\n\t\t\tif err := p.walk(sub, path+\"/\"+escapeJSONPointer(k)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/schema/prevalidate.go#L69-L105","documentation":"preValidateSchema walks an identity schema before handing it to the upstream JSON Schema compiler and pre-compiles every \"pattern\" value with Go's regexp. If a pattern is not a valid RE2 regular expression, walk returns this wrapped error instead of letting regexp.MustCompile panic deep inside the upstream compile.","triggerScenarios":"An identity schema JSON contains a \"pattern\" keyword whose string is not a valid Go RE2 regex, e.g. \"(?<name>...)\" (Go RE2 does not support lookbehind or certain group naming), unbalanced parentheses, or a trailing backslash. Raised during pre-validation of any identity schema submitted for compilation.","commonSituations":"Patterns copied from JavaScript/PCRE-flavored validators that use lookaheads ((?=...)) or backreferences, which Go's RE2 engine does not support; typos like unclosed character classes; patterns built dynamically from user input that contain regex metacharacters.","solutions":["Fix the \"pattern\" value in the identity schema so it compiles as a Go RE2 regular expression (regexp.Compile).","Remove unsupported constructs: lookaheads/lookbehinds ((?=...), (?!...), (?<=...)) and backreferences are not valid in RE2 — restructure the pattern or validate those parts in application code instead.","Test the regex locally with a small Go snippet (regexp.Compile) or an RE2-compatible tester before submitting the schema.","Escape metacharacters that were meant literally (e.g. use \\. for a literal dot) to fix 'missing closing )' or 'missing argument to repetition operator' errors."],"exampleFix":"// before\n\"pattern\": \"^(?=.*[A-Z]).+$\"   // lookahead, unsupported by RE2\n// after\n\"pattern\": \"^[A-Za-z0-9]*[A-Z][A-Za-z0-9]*$\"   // RE2-compatible equivalent","handlingStrategy":"validation","validationCode":"func validatePattern(p string) error {\n    if _, err := regexp.Compile(p); err != nil {\n        return fmt.Errorf(\"pattern %q invalid: %w\", p, err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var re *syntax.Error\nif errors.As(err, &re) {\n    log.Printf(\"fix RE2 regex: %v (code=%v expr=%q)\", re, re.Code, re.Expr)\n}","preventionTips":["Test all patterns with Go regexp.Compile before adding them to schemas","Avoid PCRE-only features (lookarounds, backreferences) — write RE2-compatible patterns","Escape regex metacharacters when patterns embed literal user text"],"tags":["regex","jsonschema","identity-schema","validation"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}