From b56ca8842e934647e75067cf9118e63a3a346dd5 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 12 Aug 2025 21:42:01 +1000 Subject: [PATCH] fix(mm): fail when model exists at path instead of finding unused new path When installing a model, the previous, graceful logic would increment a suffix on the destination path until found a free path for the model. But because model file installation and record creation are not in a transaction, we could end up moving the file successfully and fail to create the record: - User attempts to install an already-installed model - Attempt to move the downloaded model from download tempdir to destination path - The path already exists - Add `_1` or similar to the path until we find a path that is free - Move the model - Create the model record - FK constraint violation bc we already have a model w/ that name, but the model file has already been moved into the invokeai dir. Closes #8416 --- .../services/model_install/model_install_default.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/invokeai/app/services/model_install/model_install_default.py b/invokeai/app/services/model_install/model_install_default.py index 9cfc7fdaa97..2a6e638876e 100644 --- a/invokeai/app/services/model_install/model_install_default.py +++ b/invokeai/app/services/model_install/model_install_default.py @@ -623,16 +623,13 @@ def _move_model(self, old_path: Path, new_path: Path) -> Path: if old_path == new_path: return old_path + if new_path.exists(): + raise FileExistsError(f"Cannot move {old_path} to {new_path}: destination already exists") + new_path.parent.mkdir(parents=True, exist_ok=True) - # if path already exists then we jigger the name to make it unique - counter: int = 1 - while new_path.exists(): - path = new_path.with_stem(new_path.stem + f"_{counter:02d}") - if not path.exists(): - new_path = path - counter += 1 move(old_path, new_path) + return new_path def _probe(self, model_path: Path, config: Optional[ModelRecordChanges] = None):