invoke-ai/InvokeAI · error · ImageFileDeleteException

ImageFileDeleteException

Error message

ImageFileDeleteException

What it means

ImageFilesDisk.stage_delete() performs a two-phase delete: files are moved into a staging directory, and if any move fails the already-staged files are rolled back (restored in reverse order), the staging directory is removed, and this ImageFileDeleteException is raised with the original error chained. It means the delete could not even be prepared; the original files are left intact.

Source

Thrown at invokeai/app/services/image_files/image_files_disk.py:230

            with open(staging_dir / "manifest.json", "w", encoding="utf-8") as manifest:
                manifest.write(json.dumps({"image_name": image_name, "image_subfolder": image_subfolder}))
                manifest.flush()
                os.fsync(manifest.fileno())
            for index, source in enumerate(candidates):
                with self.__cache_lock:
                    self.__cache.pop(source, None)
                if source.exists():
                    destination = staging_dir / str(index)
                    source.replace(destination)
                    staged.append((source, destination))
            return _StagedDelete(directory=staging_dir, files=staged)
        except Exception as e:
            for source, destination in reversed(staged):
                if destination.exists():
                    source.parent.mkdir(parents=True, exist_ok=True)
                    destination.replace(source)
            shutil.rmtree(staging_dir, ignore_errors=True)
            raise ImageFileDeleteException from e

    def commit_delete(self, token: object) -> None:
        if not isinstance(token, _StagedDelete):
            raise ImageFileDeleteException("Invalid staged-delete token")
        try:
            shutil.rmtree(token.directory)
        except Exception as e:
            raise ImageFileDeleteException from e

    def rollback_delete(self, token: object) -> None:
        if not isinstance(token, _StagedDelete):
            raise ImageFileDeleteException("Invalid staged-delete token")
        try:
            for source, destination in reversed(token.files):
                if destination.exists():
                    source.parent.mkdir(parents=True, exist_ok=True)
                    destination.replace(source)
            shutil.rmtree(token.directory, ignore_errors=True)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Check the chained cause to see which file operation failed and whether the source file still exists
  2. Fix permissions on the output folder and its parent so staging moves can succeed
  3. If the file is already gone, clear the stale record instead of calling delete again
  4. Ensure no external process (sync/backup tooling) is racing with the delete

Example fix

// before
services.images.delete(image_name)  # may raise raw OSError
// after
from invokeai.app.services.image_files.image_files_common import ImageFileDeleteException
try:
    services.images.delete(image_name)
except ImageFileDeleteException as e:
    logger.warning(f"delete failed, file left intact: {e.__cause__}")
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path
p = Path(services.images.get_path(image_name, image_subfolder=subfolder))
if not p.exists():
    raise FileNotFoundError(f"cannot delete, file already gone: {p}")

Try / catch

try:
    services.images.delete(image_name)
except ImageFileDeleteException as e:
    logger.warning(f"delete aborted, files left intact: {e.__cause__}")

Prevention

When it happens

Trigger: Calling stage_delete (or delete(), which wraps it) when moving the image or thumbnail into the staging directory raises — e.g. the source file was already removed, or destination/source paths are unwritable or locked.

Common situations: Image file deleted externally between API call and staging; permission problems on output or staging directories; file held open/locked by another process on some platforms; inconsistent subfolder layout after manual file moves.

Related errors


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