blakeblackshear/frigate · error · FileNotFoundError

Custom model zip not found

Error message

Custom model zip not found: {self.memx_model_path}

What it means

The memryx detector was given a custom model zip path (it ends with .zip) but os.path.exists fails, so check_and_prepare_model raises FileNotFoundError. The file is simply not present at that location inside the Frigate container.

Solutions

  1. docker exec into the container and confirm the zip exists at the exact configured path
  2. Fix/add the volume mount mapping the host models dir to the container path used in config
  3. Correct filename typos and ensure mounts are available before Frigate starts

Example fix

# before
path: /models/memryx/model.zip  # not mounted
# after (docker-compose)
volumes:
  - /host/models:/models
# path: /models/model.zip
Defensive patterns

Strategy: validation

Validate before calling

import os

def zip_exists(path: str) -> bool:
    return path.endswith('.zip') and os.path.isfile(path)

Try / catch

try:
    detector = MemryXDetector(config)
except FileNotFoundError as e:
    if 'Custom model zip not found' in str(e):
        raise SystemExit(f'Mount/verify {path} inside the container') from None
    raise

Prevention

When it happens

Trigger: Configuring a .zip model path that does not exist in the container: unmounted volume, host path used instead of container path, typo, or file not yet synced.

Common situations: Missing docker volume mount for the models directory; path correct on host but not in container; USB/NAS mount not ready at container start; case-sensitive filename mismatch.

Related errors


AI-assisted analysis of blakeblackshear/frigate@ca18b8dc13 (2026-08-27). Data as JSON: /api/errors/d4265f2cd9925e6c. Report an issue: GitHub.

Appendix: source

Thrown at frigate/detectors/plugins/memryx.py:209

            raise

    def check_and_prepare_model(self):
        if not os.path.exists(self.cache_dir):
            os.makedirs(self.cache_dir, exist_ok=True)

        lock_path = os.path.join(self.cache_dir, f".{self.model_folder}.lock")
        lock = FileLock(lock_path, timeout=60)

        with lock:
            # ---------- CASE 1: user provided a custom model path ----------
            if self.memx_model_path:
                if not self.memx_model_path.endswith(".zip"):
                    raise ValueError(
                        f"Invalid model path: {self.memx_model_path}. "
                        "Only .zip files are supported. Please provide a .zip model archive."
                    )
                if not os.path.exists(self.memx_model_path):
                    raise FileNotFoundError(
                        f"Custom model zip not found: {self.memx_model_path}"
                    )

                logger.info(f"User provided zip model: {self.memx_model_path}")

                # Extract custom zip into a separate area so it never clashes with MemryX cache
                custom_dir = os.path.join(
                    self.cache_dir, "custom_models", self.model_folder
                )
                if os.path.isdir(custom_dir):
                    shutil.rmtree(custom_dir)
                os.makedirs(custom_dir, exist_ok=True)

                with zipfile.ZipFile(self.memx_model_path, "r") as zip_ref:
                    zip_ref.extractall(custom_dir)
                logger.info(f"Custom model extracted to {custom_dir}.")

                # Find .dfp and optional *_post.onnx recursively

View on GitHub (pinned to ca18b8dc13)