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
- Check the chained cause to see which file operation failed and whether the source file still exists
- Fix permissions on the output folder and its parent so staging moves can succeed
- If the file is already gone, clear the stale record instead of calling delete again
- 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
- Confirm the image exists before deleting to avoid racing with external removals
- Keep permissions consistent on output and staging directories
- Pause backup/sync tools that lock output files during maintenance deletes
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
- ImageFileNotFoundException
- ImageFileSaveException
- Invalid staged-delete token
- Failed to add image to board
- str(e)
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/856b4885bdf37530.
Report an issue: GitHub.