dgtlmoon/changedetection.io · error

Processor '{processor_name}' does not support xlsx export

Error message

Processor '{processor_name}' does not support xlsx export

What it means

abort(404) in the xlsx export endpoint when the watch's processor does not implement export_xlsx(). Only processors that provide a spreadsheet export (e.g. restock price/stock timelines) support /diff/<uuid>/processor-export.xlsx; others fall through to this 404.

Source

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

            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'))

        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, 'export_xlsx'):
            data, filename = processor_module.export_xlsx(watch=watch, datastore=datastore)
            resp = make_response(data)
            resp.headers['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            resp.headers['Content-Disposition'] = f'attachment; filename="{filename}"'
            return resp

        abort(404, description=f"Processor '{processor_name}' does not support xlsx export")

    @diff_blueprint.route("/diff/<uuid_str:uuid>/extract", methods=['GET'])
    @login_optionally_required
    def diff_history_page_extract_GET(uuid):
        """
        Render the data extraction form for a watch.

        This route is processor-aware: it delegates to the processor's
        extract.py module, allowing different processor types to provide
        custom extraction interfaces.

        Each processor implements processors/{type}/extract.py::render_form()
        If a processor doesn't have an extract module, falls back to text_json_diff.
        """


        if uuid == 'first':
            uuid = list(datastore.data['watching'].keys()).pop()

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Confirm the watch's processor type supports xlsx export (e.g. restock processors)
  2. Switch the watch to a processor that implements export_xlsx before requesting the export
  3. If writing a custom processor, implement export_xlsx(watch, datastore) returning (data, filename)

Example fix

# before
resp = requests.get(f'{base}/diff/{uuid}/processor-export.xlsx')
resp.raise_for_status()

# after
resp = requests.get(f'{base}/diff/{uuid}/processor-export.xlsx')
if resp.status_code == 404:
    raise RuntimeError('processor has no xlsx export; use a restock processor')
resp.raise_for_status()
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

def can_export_xlsx(processor_module) -> bool:
    return hasattr(processor_module, 'export_xlsx') and callable(processor_module.export_xlsx)

Try / catch

try:
    data, filename = processor_module.export_xlsx(watch=watch, datastore=datastore)
except (AttributeError, TypeError):
    abort(404, description="Processor does not support xlsx export")

Prevention

When it happens

Trigger: GET /diff/<uuid>/processor-export.xlsx for a watch whose processor module lacks an export_xlsx(watch, datastore) function (the hasattr check fails), or the processor submodule lookup returned None.

Common situations: Trying to export history from the default 'text' watch/processor which has no xlsx exporter; custom processors that never implemented export_xlsx; expecting parity with processors that do support export.

Related errors


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