dgtlmoon/changedetection.io · warning · ValidationError

Bounding box values must be non-negative

Error message

Bounding box values must be non-negative

What it means

After the format regex passes, the validator splits the value and rejects any component less than 0. In practice this branch is nearly unreachable because the regex \d+ already forbids minus signs — it exists as defence-in-depth against refactors of the regex.

Source

Thrown at changedetectionio/processors/image_ssim_diff/forms.py:29


def validate_bounding_box(form, field):
    """Validate bounding box format: x,y,width,height with integers."""
    if not field.data:
        return  # Optional field

    if len(field.data) > 100:
        raise ValidationError(_l('Bounding box value is too long'))

    # Should be comma-separated integers
    if not re.match(r'^\d+,\d+,\d+,\d+$', field.data):
        raise ValidationError(_l('Bounding box must be in format: x,y,width,height (integers only)'))

    # Validate values are reasonable (not negative, not ridiculously large)
    parts = [int(p) for p in field.data.split(',')]
    for part in parts:
        if part < 0:
            raise ValidationError(_l('Bounding box values must be non-negative'))
        if part > 10000:  # Reasonable max screen dimension
            raise ValidationError(_l('Bounding box values are too large'))


def validate_selection_mode(form, field):
    """Validate selection mode value."""
    if not field.data:
        return  # Optional field

    if field.data not in ['element', 'draw']:
        raise ValidationError(_l('Selection mode must be either "element" or "draw"'))


class processor_settings_form(processor_text_json_diff_form):
    """Form for fast image comparison processor settings."""

    processor_config_min_change_percentage = IntegerField(
        _l('Minimum Change Percentage'),

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Keep the strict ^\d+,\d+,\d+,\d+$ regex so negative values are rejected earlier
  2. If you fork/relax the regex, keep this non-negative check in place
  3. Clamp or reject negative coordinates at the source (region-selection UI)
Defensive patterns

Strategy: validation

Validate before calling

parts = [int(p) for p in bbox.split(',')]
assert all(p >= 0 for p in parts)

Type guard

def bbox_components_non_negative(s: str) -> bool:
    return all(int(p) >= 0 for p in s.split(','))

Prevention

When it happens

Trigger: Only reachable if the format regex is relaxed (e.g. to allow signed ints) or the validator is reused with different pre-checks; with the shipped regex, '-10,20,300,400' fails earlier at the format check, not here.

Common situations: Custom forks that loosen the regex to accept '+/'-prefixed numbers; copy-pasting this validator into other projects without keeping the \d+ regex in sync.

Related errors


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