dgtlmoon/changedetection.io · error

Processor '{processor_name}' does not provide difference dat

Error message

Processor '{processor_name}' does not provide difference data

What it means

abort(404) in the diff blueprint when the requested watch processor either has no 'difference' submodule or that submodule does not expose a get_data() function. changedetection.io delegates processor-specific difference views (e.g. text vs restock/stock timelines) to per-processor submodules; requesting difference data from a processor that implements none yields this 404.

Source

Thrown at changedetectionio/blueprint/ui/diff.py:364

        if the watch's processor doesn't implement get_data().
        """
        from flask import jsonify, abort

        if uuid == 'first':
            uuid = list(datastore.data['watching'].keys()).pop()
        try:
            watch = datastore.data['watching'][uuid]
        except KeyError:
            return jsonify({'error': 'Watch not found'}), 404

        processor_name = watch.get('processor', 'text_json_diff')
        from changedetectionio.processors import get_processor_submodule
        processor_module = get_processor_submodule(processor_name, 'difference')

        if processor_module and hasattr(processor_module, 'get_data'):
            return jsonify(processor_module.get_data(watch=watch, datastore=datastore, request=request))

        abort(404, description=f"Processor '{processor_name}' does not provide difference data")

    @diff_blueprint.route("/diff/<uuid_str:uuid>/processor-export.xlsx", methods=['GET'])
    @login_optionally_required
    def diff_history_page_processor_export(uuid):
        """
        Download the processor's history as an .xlsx (e.g. the restock price/stock timeline).
        Processor-aware: delegates to processors/{type}/difference.py::export_xlsx(), which
        returns (bytes, filename). 404 if the processor doesn't implement it.
        """
        from flask import make_response, abort

        if uuid == 'first':
            uuid = list(datastore.data['watching'].keys()).pop()
        try:
            watch = datastore.data['watching'][uuid]
        except KeyError:
            flash(gettext("No history found for the specified link, bad link?"), "error")
            return redirect(url_for('watchlist.index'))

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Check changedetectionio/processors/<name>/difference.py exists and defines get_data(watch, datastore, request) for your processor
  2. Verify the processor name in the URL matches an installed processor (text_monitor, restock etc.)
  3. If you maintain a custom processor, add a difference submodule exposing get_data

Example fix

# before
abort(404, description=f"Processor '{processor_name}' does not provide difference data")

# after (custom processor)
# changedetectionio/processors/my_proc/difference.py
def get_data(watch, datastore, request):
    return {'snapshot_count': len(watch.history)}
Defensive patterns

Strategy: validation

Validate before calling

from changedetectionio.processors import get_processor_submodule
def processor_has_diff_data(name):
    m = get_processor_submodule(name, 'difference')
    return m is not None and hasattr(m, 'get_data')

Type guard

def supports_diff_data(processor_name: str) -> bool:
    """True if the processor exposes difference data."""
    m = get_processor_submodule(processor_name, 'difference')
    return bool(m and hasattr(m, 'get_data'))

Try / catch

from flask import abort
try:
    return jsonify(processor_module.get_data(watch=watch, datastore=datastore, request=request))
except NotFound:
    return 'difference data unavailable', 404

Prevention

When it happens

Trigger: GET /diff/<uuid>/processor-data?processor=<name> where <name> is a processor without a difference submodule/get_data (e.g. a processor that only renders extracted data), or an unknown/misspelled processor name (get_processor_submodule returns None).

Common situations: Custom or third-party processors that implement rendering but not the difference data API; UI links carried over from another watch type after the processor was changed; typos in the processor query parameter.

Related errors


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