dgtlmoon/changedetection.io · warning

Asset '{asset_name}' not found

Error message

Asset '{asset_name}' not found

What it means

Same pattern as the diff asset endpoint, on the preview blueprint: the processor's get_asset() was called and returned None, so no asset with the requested name exists for this watch, and the handler aborts with 404 naming the missing asset.

Source

Thrown at changedetectionio/blueprint/ui/preview.py:174

        # Get the processor type for this watch
        processor_name = watch.get('processor', 'text_json_diff')

        # Try to get the processor's preview module (works for both built-in and plugin processors)
        from changedetectionio.processors import get_processor_submodule
        processor_module = get_processor_submodule(processor_name, 'preview')

        # Call the processor's get_asset() function
        if processor_module and hasattr(processor_module, 'get_asset'):
            result = processor_module.get_asset(
                asset_name=asset_name,
                watch=watch,
                datastore=datastore,
                request=request
            )

            if result is None:
                from flask import abort
                abort(404, description=f"Asset '{asset_name}' not found")

            binary_data, content_type, cache_control = result

            response = make_response(binary_data)
            response.headers['Content-Type'] = content_type
            if cache_control:
                response.headers['Cache-Control'] = cache_control
            return response
        else:
            logger.warning(f"Processor {processor_name} does not implement get_asset()")
            from flask import abort
            abort(404, description=f"Processor '{processor_name}' does not support assets")

    return preview_blueprint

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Run a check for the watch to (re)generate the asset
  2. Use the asset name exposed by the current preview page/processor, not a cached one
  3. Inspect watch.data_dir to confirm the expected asset file exists

Example fix

# before
resp = requests.get(f'{base}/preview/{uuid}/asset/last-screenshot.png')
resp.raise_for_status()

# after
resp = requests.get(f'{base}/preview/{uuid}/asset/last-screenshot.png')
if resp.status_code == 404:
    resp = regenerate_then_fetch(uuid)
resp.raise_for_status()
Defensive patterns

Strategy: fallback

Validate before calling

import os
def preview_asset_ready(watch, asset_name):
    return os.path.isfile(os.path.join(watch.data_dir, asset_name))

Try / catch

try:
    r = requests.get(preview_asset_url)
    r.raise_for_status()
except requests.HTTPError as e:
    if e.response.status_code == 404:
        return PLACEHOLDER
    raise

Prevention

When it happens

Trigger: GET /preview/<uuid>/asset/<asset_name> before the asset was generated by a check, after the asset file was deleted/pruned, or with a misspelled/stale asset name.

Common situations: Loading a preview page right after watch creation (first check hasn't run); referencing an asset captured in an earlier snapshot version after data pruning.

Related errors


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