invoke-ai/InvokeAI · error · NotAMatchError

model path is not a directory

Error message

model path is not a directory

What it means

raise_if_not_dir asserts that the ModelOnDisk path is a directory. Config classes for diffusers-style formats (which consist of a folder with config.json plus weight files) call this during from_model_on_disk; a plain file path fails the check with NotAMatchError so other config classes can be attempted.

Source

Thrown at invokeai/backend/model_manager/configs/identification_utils.py:166

    for field_name, override_value in override_fields.items():
        if field_name not in candidate_config_class.model_fields:
            raise NotAMatchError(f"unknown override field: {field_name}")
        try:
            PydanticFieldValidator.validate_field(candidate_config_class, field_name, override_value)
        except ValidationError as e:
            raise NotAMatchError(f"invalid override for field '{field_name}': {e}") from e


def raise_if_not_file(mod: ModelOnDisk) -> None:
    """Raise NotAMatch if the model path is not a file."""
    if not mod.path.is_file():
        raise NotAMatchError("model path is not a file")


def raise_if_not_dir(mod: ModelOnDisk) -> None:
    """Raise NotAMatch if the model path is not a directory."""
    if not mod.path.is_dir():
        raise NotAMatchError("model path is not a directory")


def state_dict_has_any_keys_exact(state_dict: dict[str | int, Any], keys: str | set[str]) -> bool:
    """Returns true if the state dict has any of the specified keys."""
    _keys = {keys} if isinstance(keys, str) else keys
    return any(key in state_dict for key in _keys)


def state_dict_has_any_keys_starting_with(state_dict: dict[str | int, Any], prefixes: str | set[str]) -> bool:
    """Returns true if the state dict has any keys starting with any of the specified prefixes."""
    _prefixes = {prefixes} if isinstance(prefixes, str) else prefixes
    return any(any(key.startswith(prefix) for prefix in _prefixes) for key in state_dict.keys() if isinstance(key, str))


def state_dict_has_any_keys_ending_with(state_dict: dict[str | int, Any], suffixes: str | set[str]) -> bool:
    """Returns true if the state dict has any keys ending with any of the specified suffixes."""
    _suffixes = {suffixes} if isinstance(suffixes, str) else suffixes
    return any(any(key.endswith(suffix) for suffix in _suffixes) for key in state_dict.keys() if isinstance(key, str))

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Pass the diffusers model directory (the folder containing model_index.json/config.json) instead of the weights file.
  2. Convert the single-file checkpoint to diffusers format (e.g. diffusers conversion script) to obtain the expected folder layout.
  3. If the model really is single-file, use the matching single-file config class.
  4. Confirm the directory exists and is not a symlink to a file.

Example fix

// before
ModelOnDisk(Path("/models/flux/flux1-dev.safetensors"))
// after
ModelOnDisk(Path("/models/flux/flux1-dev"))  # diffusers directory
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
p = Path(model_path)
assert p.is_dir() and (p / "model_index.json").exists(), f"expected a diffusers model directory: {p}"

Type guard

def is_diffusers_dir(p) -> bool:
    from pathlib import Path
    d = Path(p)
    return d.is_dir() and ((d / "model_index.json").exists() or (d / "config.json").exists())

Try / catch

try:
    record = from_model_on_disk(mod)
except NotAMatchError as e:
    if str(e) == "model path is not a directory":
        logger.warning("single file probed with directory config; will retry file-based config")

Prevention

When it happens

Trigger: from_model_on_disk probing a diffusers/folder-based config class against a single .safetensors or .ckpt file path.

Common situations: Registering a single checkpoint file where a converted diffusers folder is expected; users placing a file where the scanner expects a repo-style directory; incomplete conversions leaving only files, not the expected folder layout.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/573cbaeddfb8aa06. Report an issue: GitHub.