{"record":{"id":"d80e8dcdf19eed37","repo":"dgtlmoon/changedetection.io","slug":"regex-s-is-not-a-valid-regular-expression","errorCode":null,"errorMessage":"RegEx '%s' is not a valid regular expression.","messagePattern":"RegEx '(.+?)' is not a valid regular expression\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"warning","filePath":"changedetectionio/forms.py","lineNumber":648,"sourceCode":"    has opted in via ALLOW_IANA_RESTRICTED_ADDRESSES=true.\"\"\"\n\n    def __call__(self, form, field):\n        from changedetectionio.validate_url import is_llm_api_base_safe\n        ok, reason = is_llm_api_base_safe(field.data)\n        if not ok:\n            raise ValidationError(reason)\n\n\nclass ValidateSinglePythonRegexString(object):\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        try:\n            re.compile(field.data)\n        except re.error:\n            message = field.gettext('RegEx \\'%s\\' is not a valid regular expression.')\n            raise ValidationError(message % (field.data))\n\n\nclass ValidateListRegex(object):\n    \"\"\"\n    Validates that anything that looks like a regex passes as a regex\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n\n        for line in field.data:\n            if re.search(html_tools.PERL_STYLE_REGEX, line, re.IGNORECASE):\n                try:\n                    regex = html_tools.perl_style_slash_enclosed_regex_to_options(line)\n                    re.compile(regex)\n                except re.error:\n                    message = field.gettext('RegEx \\'%s\\' is not a valid regular expression.')","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/forms.py#L630-L666","documentation":"A WTForms custom validator that compiles the field's value with re.compile() and converts re.error into wtforms.ValidationError with the message \"RegEx '<pattern>' is not a valid regular expression.\". It is used for single regex-valued fields so invalid patterns are rejected at form-validation time rather than crashing the watcher later.","triggerScenarios":"Submitting a form where the regex field contains a pattern Python's re module cannot compile, e.g. an unmatched parenthesis '(' , bad repeat like 'a{2,1}', or trailing backslash 'foo\\\\'. re.compile raises re.error and the validator re-raises as ValidationError.","commonSituations":"Copy-pasting PCRE/JavaScript-only regex (lookbehind groups unsupported in old Python versions, POSIX classes), unbalanced brackets, or escaping mistakes when moving regexes between YAML config, shell, and form input.","solutions":["Test the pattern locally: python -c \"import re; re.compile(r'YOUR_PATTERN')\" and fix the reported error","Balance parentheses/brackets and fix invalid quantifier ranges like {2,1}","Double-escape backslashes when the pattern passes through YAML/JSON/shell layers"],"exampleFix":"# before\nre.compile('foo(')\n# after\nre.compile('foo\\\\(')\n","handlingStrategy":"validation","validationCode":"import re\n\ndef regex_ok(pattern: str) -> bool:\n    try:\n        re.compile(pattern)\n        return True\n    except re.error:\n        return False\n","typeGuard":"import re\n\ndef is_valid_regex(p: str) -> bool:\n    try:\n        re.compile(p); return True\n    except re.error:\n        return False\n","tryCatchPattern":"try:\n    re.compile(pattern)\nexcept re.error as e:\n    flash(f'Bad regex: {e}')\n","preventionTips":["Compile-test every regex before saving it to config","Use raw strings (r'...') in Python code","Watch escaping when patterns travel through YAML/JSON"],"tags":["regex","python-re","wtforms","validation"],"backgroundTag":"invalid-regular-expression","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}