dgtlmoon/changedetection.io · warning · ValidationError

RegEx '%s' is not a valid regular expression.

Error message

RegEx '%s' is not a valid regular expression.

What it means

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.

Source

Thrown at changedetectionio/forms.py:648

    has opted in via ALLOW_IANA_RESTRICTED_ADDRESSES=true."""

    def __call__(self, form, field):
        from changedetectionio.validate_url import is_llm_api_base_safe
        ok, reason = is_llm_api_base_safe(field.data)
        if not ok:
            raise ValidationError(reason)


class ValidateSinglePythonRegexString(object):
    def __init__(self, message=None):
        self.message = message

    def __call__(self, form, field):
        try:
            re.compile(field.data)
        except re.error:
            message = field.gettext('RegEx \'%s\' is not a valid regular expression.')
            raise ValidationError(message % (field.data))


class ValidateListRegex(object):
    """
    Validates that anything that looks like a regex passes as a regex
    """
    def __init__(self, message=None):
        self.message = message

    def __call__(self, form, field):

        for line in field.data:
            if re.search(html_tools.PERL_STYLE_REGEX, line, re.IGNORECASE):
                try:
                    regex = html_tools.perl_style_slash_enclosed_regex_to_options(line)
                    re.compile(regex)
                except re.error:
                    message = field.gettext('RegEx \'%s\' is not a valid regular expression.')

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Test the pattern locally: python -c "import re; re.compile(r'YOUR_PATTERN')" and fix the reported error
  2. Balance parentheses/brackets and fix invalid quantifier ranges like {2,1}
  3. Double-escape backslashes when the pattern passes through YAML/JSON/shell layers

Example fix

# before
re.compile('foo(')
# after
re.compile('foo\\(')
Defensive patterns

Strategy: validation

Validate before calling

import re

def regex_ok(pattern: str) -> bool:
    try:
        re.compile(pattern)
        return True
    except re.error:
        return False

Type guard

import re

def is_valid_regex(p: str) -> bool:
    try:
        re.compile(p); return True
    except re.error:
        return False

Try / catch

try:
    re.compile(pattern)
except re.error as e:
    flash(f'Bad regex: {e}')

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dgtlmoon/changedetection.io@5d9c7c6da7 (2026-08-27). Data as JSON: /api/errors/d80e8dcdf19eed37. Report an issue: GitHub.