{"record":{"id":"3d570e7b2d4af3a3","repo":"invoke-ai/InvokeAI","slug":"imagefilesaveexception","errorCode":null,"errorMessage":"ImageFileSaveException","messagePattern":"ImageFileSaveException","errorType":"exception","errorClass":"ImageFileSaveException","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_files/image_files_disk.py","lineNumber":198,"sourceCode":"                **save_options,\n            )\n\n            thumbnail_image.save(thumbnail_path)\n\n            self.__set_cache(image_path, image)\n            self.__set_cache(thumbnail_path, thumbnail_image)\n        except Exception as e:\n            # A thumbnail failure must not leave a full-size image with no thumbnail. The\n            # names are normally new, but preserve any pre-existing files when save() is\n            # used to overwrite an existing image.\n            for path, existed in ((image_path, image_existed), (thumbnail_path, thumbnail_existed)):\n                if path is not None and not existed:\n                    try:\n                        path.unlink(missing_ok=True)\n                    except OSError:\n                        pass\n            self.evict_cache_paths([path for path in (image_path, thumbnail_path) if path is not None])\n            raise ImageFileSaveException from e\n\n    def delete(self, image_name: str, image_subfolder: str = \"\") -> None:\n        token = self.stage_delete(image_name, image_subfolder)\n        self.commit_delete(token)\n\n    def stage_delete(self, image_name: str, image_subfolder: str = \"\") -> _StagedDelete:\n        candidates = [\n            self.get_path(image_name, image_subfolder=image_subfolder),\n            self.get_path(image_name, thumbnail=True, image_subfolder=image_subfolder),\n        ]\n        staging_dir = Path(tempfile.mkdtemp(prefix=\".delete_\", dir=self.__output_folder))\n        staged: list[tuple[Path, Path]] = []\n        try:\n            with open(staging_dir / \"manifest.json\", \"w\", encoding=\"utf-8\") as manifest:\n                manifest.write(json.dumps({\"image_name\": image_name, \"image_subfolder\": image_subfolder}))\n                manifest.flush()\n                os.fsync(manifest.fileno())\n            for index, source in enumerate(candidates):","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_files/image_files_disk.py#L180-L216","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nservices.images.save(image, image_name)  # ImageFileSaveException: [Errno 28] No space left\n// after\n# fix host/volume first, then retry\n$ df -h /invokeai/outputs && chmod u+rwX /invokeai/outputs\nservices.images.save(image, image_name)","handlingStrategy":"validation","validationCode":"import shutil\nfrom pathlib import Path\nout = Path(services.images.get_path(\"__probe__\")).parent\nout.mkdir(parents=True, exist_ok=True)\nprobe = out / \".write_probe\"\nprobe.write_bytes(b\"\")\nprobe.unlink()\nif shutil.disk_usage(out).free < 100 * 1024 * 1024:\n    raise RuntimeError(\"Output volume low on disk\")","typeGuard":null,"tryCatchPattern":"try:\n    services.images.save(image, image_name)\nexcept ImageFileSaveException as e:\n    logger.error(f\"image save failed: {e.__cause__}\")\n    raise HTTPException(500, \"Could not persist image; check disk space/permissions\")","preventionTips":["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"],"tags":["storage","disk-io","image-files","save-failed"],"backgroundTag":"disk-write-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}