invoke-ai/InvokeAI · error · OSError

Not a valid file or directory: {model_path}

Error message

Not a valid file or directory: {model_path}

What it means

ModelHash.hash raises OSError when the given path is neither an existing file nor an existing directory. The method dispatches on is_file()/is_dir() and falls through to this error when both checks fail.

Source

Thrown at invokeai/backend/model_hash/model_hash.py:109

            str: Hexdigest of the hash of the model
        """

        model_path = Path(model_path)
        # blake3_single is a single-threaded version of blake3, prefix should still be "blake3:"
        prefix = self._get_prefix(self.algorithm)
        if model_path.is_file():
            hash_ = None
            # To give a similar user experience for single files and directories, we use a progress bar even for single files
            pbar = tqdm([model_path], desc=f"Hashing {model_path.name}", unit="file")
            for component in pbar:
                pbar.set_description(f"Hashing {component.name}")
                hash_ = prefix + self._hash_file(model_path)
            assert hash_ is not None
            return hash_
        elif model_path.is_dir():
            return prefix + self._hash_dir(model_path)
        else:
            raise OSError(f"Not a valid file or directory: {model_path}")

    def _hash_dir(self, dir: Path) -> str:
        """Compute the hash for all files in a directory and return a hexdigest.

        Args:
            dir: Path to the directory

        Returns:
            str: Hexdigest of the hash of the directory
        """
        model_component_paths = self._get_file_paths(dir, self._file_filter)

        component_hashes: list[str] = []
        pbar = tqdm(sorted(model_component_paths), desc=f"Hashing {dir.name}", unit="file")
        for component in pbar:
            pbar.set_description(f"Hashing {component.name}")
            component_hashes.append(self._hash_file(component))

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the path exists: Path(model_path).exists() before calling hash().
  2. Fix the path typo or rebuild it from the model config's actual location.
  3. Re-point the model record to the new location if the model was moved, or re-register/re-scan the model folder.
  4. Check mounts/permissions if the path should exist (broken symlink or missing mount).

Example fix

// before
h = hasher.hash('/models/typo-name.safetensors')  # OSError
// after
p = Path('/models/real-name.safetensors')
assert p.exists(), f'missing: {p}'
h = hasher.hash(p)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def path_is_hashable(model_path: str | Path) -> bool:
    p = Path(model_path)
    return p.is_file() or p.is_dir()

Type guard

def is_existing_path(p: object) -> TypeGuard[Path]:
    return isinstance(p, Path) and (p.is_file() or p.is_dir())

Try / catch

try:
    digest = hasher.hash(model_path)
except OSError as e:
    logger.error(f'Model path missing or invalid: {e}')
    raise ModelNotFoundError(model_path) from e

Prevention

When it happens

Trigger: Calling hasher.hash(model_path) with a non-existent path, a deleted model directory, a broken symlink, a dangling mount, or a Path containing a typo / wrong case.

Common situations: Model was moved or deleted after registration in the DB; autoimport scan directories removed; path built with wrong base (relative vs absolute); network mount not mounted when hashing.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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