dgtlmoon/changedetection.io · warning · ValidationError

Empty value not allowed.

Error message

Empty value not allowed.

What it means

A MultiLineField-style WTForms validator that splits input into lines raises ValidationError when a line is empty (after strip) and allow_empty is False. It means the submitted multi-line value contained a blank line where the field configuration forbids empty entries.

Source

Thrown at changedetectionio/forms.py:816

    def __call__(self, form, field):
        data = field.data
        if not data:
            return

        # normalize into list of lines
        if isinstance(data, str) and self.split_lines:
            lines = data.splitlines()
        elif isinstance(data, (list, tuple)):
            lines = data
        else:
            lines = [data]

        for line in lines:
            stripped = line.strip()
            if not stripped:
                if self.allow_empty:
                    continue
                raise ValidationError(self.message or _l("Empty value not allowed."))
            if not self.pattern.match(stripped):
                raise ValidationError(self.message or _l("Invalid value."))

def visual_browser_choices():
    """Browsers that can render the Add-Watch live preview, as RadioField choices.

    Lazy import (the add_watch_ui blueprint imports this module) and empty outside an
    app context, because WTForms evaluates a choices callable on field construction.
    """
    from flask import current_app, has_app_context
    from changedetectionio.blueprint.add_watch_ui import browser_config

    if not has_app_context():
        return []
    datastore = current_app.config.get('DATASTORE')
    return browser_config.radio_choices(datastore) if datastore else []

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Remove blank lines from the textarea input
  2. If blank lines should be tolerated, construct the validator with allow_empty=True
  3. Pre-clean input client-side by filtering out lines that are empty after strip

Example fix

# before
validator = MultiLineRegexValidator(pattern=..., allow_empty=False)
# after
validator = MultiLineRegexValidator(pattern=..., allow_empty=True)
Defensive patterns

Strategy: validation

Validate before calling

value = form.textarea.data
lines = [l for l in value.splitlines() if l.strip()]
cleaned = '\n'.join(lines)  # submit this instead

Prevention

When it happens

Trigger: Submitting a form field validated by this class (e.g. a list of URLs/tokens, one per line) that contains a blank line, when the validator was constructed with allow_empty=False (or default). Trailing blank line with trailing whitespace still triggers it because each line is stripped first.

Common situations: Copy-pasting URL lists from spreadsheets or text files that include empty rows; a textarea auto-appending a newline; users pressing Enter twice between entries.

Related errors


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