immich-app/immich · error · ValueError

model_path must be a file with extension .armnn, .tflite or

Error message

model_path must be a file with extension .armnn, .tflite or .onnx

What it means

Raised by Ann.load() when the model_path string does not end with .armnn, .tflite, or .onnx. This is a cheap pre-check performed before touching the filesystem. Note that the higher-level _make_session only constructs AnnSession for the .armnn case, so in normal immich-ml flow this branch guards direct callers of Ann.load().

Source

Thrown at machine-learning/immich_ml/sessions/ann/loader.py:105

        self.ref_count -= 1
        if self.ref_count <= 0 and self.ann is not None:
            libann.destroy(self.ann)
            self.ann = None

    def __del__(self) -> None:
        if self.ann is not None:
            libann.destroy(self.ann)
            self.ann = None

    def load(
        self,
        model_path: str,
        fast_math: bool = True,
        fp16: bool = False,
        cached_network_path: str | None = None,
    ) -> int:
        if not model_path.endswith((".armnn", ".tflite", ".onnx")):
            raise ValueError("model_path must be a file with extension .armnn, .tflite or .onnx")
        if not exists(model_path):
            raise ValueError("model_path must point to an existing file!")

        save_cached_network = False
        if cached_network_path is not None and not exists(cached_network_path):
            save_cached_network = True
            # create empty model cache file
            open(cached_network_path, "a").close()

        net_id: int = libann.load(
            self.ann,
            model_path.encode(),
            fast_math,
            fp16,
            save_cached_network,
            cached_network_path.encode() if cached_network_path is not None else None,
        )
        if net_id < 0:

View on GitHub (pinned to 199723261c)

Solutions

  1. Check the suffix of the path passed to Ann.load(); it must be one of .armnn, .tflite, .onnx.
  2. Re-export the model to a supported format, or convert it with the Arm NN toolchain.
  3. If you have a .rknn file, use rknn.RknnSession / the RKNN pipeline instead of Ann.load.
  4. Strip any trailing slash or whitespace from the path string before calling load().

Example fix

# before
ann.load('/models/model.rknn')   # ValueError: extension must be .armnn/.tflite/.onnx

# after
ann.load('/models/model.armnn')
# or, for a Rockchip model:
from immich_ml.sessions.rknn import RknnSession
session = RknnSession(Path('/models/model.rknn'))
Defensive patterns

Strategy: validation

Validate before calling

ARMNN_SUFFIXES = ('.armnn', '.tflite', '.onnx')

def validate_armnn_model_path(model_path: str) -> None:
    if not model_path.endswith(ARMNN_SUFFIXES):
        raise ValueError(
            f"model_path {model_path!r} must end with one of {ARMNN_SUFFIXES}"
        )

# call before Ann.load():
validate_armnn_model_path(model_path)

Type guard

ARMNN_SUFFIXES = ('.armnn', '.tflite', '.onnx')

def has_armnn_suffix(model_path: str) -> bool:
    return isinstance(model_path, str) and model_path.endswith(ARMNN_SUFFIXES)

Try / catch

try:
    net_id = ann.load(model_path)
except ValueError as e:
    if 'extension .armnn' in str(e):
        raise ValueError(f"Refusing {model_path}: convert to .armnn/.tflite/.onnx first") from e
    raise

Prevention

When it happens

Trigger: Calling Ann.load() with a Path/string whose suffix is none of .armnn/.tflite/.onnx, e.g. '.rknn', '.pb', '.pt', or a path with no extension. Also triggered by a trailing slash or a path that ends in a directory name.

Common situations: Mixing up RKNN and ARMNN model files on a Rockchip board (passing a .rknn file to Ann.load); pointing at a TensorFlow frozen graph (.pb) or PyTorch (.pt) export; copy-paste error in a custom integration that calls Ann.load directly.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/7f3c332e1cd2287f. Report an issue: GitHub.