{"record":{"id":"b8808b6f39bdf9c8","repo":"dotnet/aspnetcore","slug":"regex-validator-requires-a-non-empty-pattern-par","errorCode":null,"errorMessage":"regex validator requires a non-empty \"pattern\" parameter.","messagePattern":"regex validator requires a non-empty \"pattern\" parameter\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Validation/Validators/Regex.ts","lineNumber":12,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport { ValidationContext, ValidationResult, Validator, pass, fail } from '../ValidationTypes';\n\n// Validates that the value matches a regular expression pattern (full match).\n// The pattern is anchored with ^(?:...)$ to match .NET's exact-match semantics.\n// Throws if the mandatory `pattern` parameter is missing.\nexport const regexValidator: Validator = (context: ValidationContext): ValidationResult => {\n  const { value, params } = context;\n  if (!params.pattern) {\n    throw new Error('regex validator requires a non-empty \"pattern\" parameter.');\n  }\n\n  if (!value) {\n    return pass();\n  }\n\n  // Anchor the pattern for full-match semantics, matching .NET's RegularExpressionAttribute\n  // which requires Index == 0 && Length == value.Length. The non-capturing group avoids\n  // changing semantics for patterns with alternation (e.g. \"a|b\").\n  const anchored = `^(?:${params.pattern})$`;\n\n  try {\n    return new RegExp(anchored).test(value) ? pass() : fail();\n  } catch {\n    return pass();\n  }\n};\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Validation/Validators/Regex.ts#L1-L30","documentation":"Thrown by the regex validator (Regex.ts:12) when params.pattern is falsy. This validator enforces [RegularExpression] semantics — it anchors the pattern with ^(?:...)$ for a full match against the field value. Without a pattern there is nothing to match, so it throws rather than treating empty as match-anything.","triggerScenarios":"Invoking regexValidator with a params object missing 'pattern' or pattern='' / null. Emitted from [RegularExpression(\"pattern\")]; if the data-val-regex-pattern metadata is absent the JS side has no pattern.","commonSituations":"Model has [RegularExpression] but the pattern argument is empty or stripped. Custom form rendering drops data-val-regex-pattern while keeping data-val-regex. Manually registering the validator without a pattern. Razor that conditionally renders the attribute on the wrong branch.","solutions":["Add [RegularExpression(@\"^[A-Za-z0-9]+$\")] and confirm the input renders data-val-regex-pattern=\"^[A-Za-z0-9]+$\" (and data-val-regex for the error message).","When wiring manually, pass params: { pattern: '^[A-Za-z0-9]+$' } — the validator adds the ^(?:...)$ anchoring itself, so supply the raw inner pattern.","Escape backslashes correctly in C# verbatim strings vs JS, and verify the rendered attribute is not HTML-encoded in a way that breaks the regex.","Ensure no tag helper strips data-val-regex-pattern."],"exampleFix":"// before\n<input name=\"Code\" data-val-regex />\n\n// after\n<input name=\"Code\" data-val-regex data-val-regex-pattern=\"^[A-Z]{4}$\" />","handlingStrategy":"validation","validationCode":"function hasPatternParam(params: Record<string, unknown>): boolean {\n  return Boolean(params && typeof params.pattern === 'string' && params.pattern.length > 0);\n}","typeGuard":"function isRegexConfigured(p: any): p is { pattern: string } {\n  return p && typeof p.pattern === 'string' && p.pattern.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always supply a non-empty pattern on [RegularExpression].","Confirm data-val-regex-pattern renders correctly (escape backslashes per context).","When wiring manually pass { pattern: '<rawInnerPattern>' }.","Verify HTML encoding does not mangle the pattern."],"tags":["validation","blazor","forms","regex","configuration"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}