invoke-ai/InvokeAI · error · ImageFileSaveException
ImageFileSaveException
Error message
ImageFileSaveException
What it means
ImageFilesDisk.save() failed while writing a PIL image (and/or its thumbnail) to disk — e.g. an OSError from mkdir/write — after cleaning up any partially written files and evicting cache entries. The original exception is chained as the cause. Callers of the save path (including _get_png_size consumers) see this uniform wrapper instead of the raw I/O error.
Source
Thrown at invokeai/app/services/image_files/image_files_disk.py:198
**save_options,
)
thumbnail_image.save(thumbnail_path)
self.__set_cache(image_path, image)
self.__set_cache(thumbnail_path, thumbnail_image)
except Exception as e:
# A thumbnail failure must not leave a full-size image with no thumbnail. The
# names are normally new, but preserve any pre-existing files when save() is
# used to overwrite an existing image.
for path, existed in ((image_path, image_existed), (thumbnail_path, thumbnail_existed)):
if path is not None and not existed:
try:
path.unlink(missing_ok=True)
except OSError:
pass
self.evict_cache_paths([path for path in (image_path, thumbnail_path) if path is not None])
raise ImageFileSaveException from e
def delete(self, image_name: str, image_subfolder: str = "") -> None:
token = self.stage_delete(image_name, image_subfolder)
self.commit_delete(token)
def stage_delete(self, image_name: str, image_subfolder: str = "") -> _StagedDelete:
candidates = [
self.get_path(image_name, image_subfolder=image_subfolder),
self.get_path(image_name, thumbnail=True, image_subfolder=image_subfolder),
]
staging_dir = Path(tempfile.mkdtemp(prefix=".delete_", dir=self.__output_folder))
staged: list[tuple[Path, Path]] = []
try:
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):View on GitHub (pinned to 0b6a024f2f)
Solutions
- Inspect the chained cause (__cause__) to identify the precise OSError (disk full, permission denied, etc.)
- Free disk space on the output volume if the cause is ENOSPC
- Fix permissions/ownership on the output folder so the service process can write
- Ensure the output folder is on a writable, non-read-only mount
Example fix
// before services.images.save(image, image_name) # ImageFileSaveException: [Errno 28] No space left // after # fix host/volume first, then retry $ df -h /invokeai/outputs && chmod u+rwX /invokeai/outputs services.images.save(image, image_name)
Defensive patterns
Strategy: validation
Validate before calling
import shutil
from pathlib import Path
out = Path(services.images.get_path("__probe__")).parent
out.mkdir(parents=True, exist_ok=True)
probe = out / ".write_probe"
probe.write_bytes(b"")
probe.unlink()
if shutil.disk_usage(out).free < 100 * 1024 * 1024:
raise RuntimeError("Output volume low on disk") Try / catch
try:
services.images.save(image, image_name)
except ImageFileSaveException as e:
logger.error(f"image save failed: {e.__cause__}")
raise HTTPException(500, "Could not persist image; check disk space/permissions") Prevention
- Monitor free disk space on the output volume and alert before it fills
- Run the app and the volume with matching user ownership (common Docker pitfall)
- Ensure output folder is on a writable mount (not read-only)
- Verify chained __cause__ to distinguish ENOSPC vs EACCES
When it happens
Trigger: Calling save(image, image_name) when the destination directory cannot be created or written: disk full, permission denied on the output folder, path too long, or an I/O error during PIL save or thumbnail write.
Common situations: Output volume out of disk space; wrong ownership/permissions after running the app as different users (e.g. Docker volume permission mismatch); read-only mount; subfolder names colliding with files on the filesystem.
Related errors
- ImageFileNotFoundException
- ImageFileDeleteException
- Failed to add image to board
- str(e)
- Invalid staged-delete token
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/3d570e7b2d4af3a3.
Report an issue: GitHub.