{"record":{"id":"64c350ff1d76faf5","repo":"invoke-ai/InvokeAI","slug":"imagefilenotfoundexception","errorCode":null,"errorMessage":"ImageFileNotFoundException","messagePattern":"ImageFileNotFoundException","errorType":"exception","errorClass":"ImageFileNotFoundException","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_files/image_files_disk.py","lineNumber":125,"sourceCode":"        try:\n            image_path = self.get_path(image_name, image_subfolder=image_subfolder)\n\n            cache_item = self.__get_cache(image_path)\n            if cache_item:\n                return cache_item\n\n            image = Image.open(image_path)\n            # Image.open() is lazy: it reads the header but defers pixel decoding (and holds the\n            # file handle open) until the first .load()/.copy()/.convert(). The opened object is\n            # cached and the SAME object is handed to every caller, so in multi-GPU parallel mode\n            # two worker threads can call .copy() on it concurrently and race on the shared file\n            # handle and decoder state, producing \"broken data stream\" / \"self.png is not None\"\n            # errors. Forcing the decode here makes the cached object safe for concurrent reads.\n            image.load()\n            self.__set_cache(image_path, image)\n            return image\n        except FileNotFoundError as e:\n            raise ImageFileNotFoundException from e\n\n    def save(\n        self,\n        image: PILImageType,\n        image_name: str,\n        metadata: Optional[str] = None,\n        workflow: Optional[str] = None,\n        graph: Optional[str] = None,\n        thumbnail_size: int = 256,\n        image_subfolder: str = \"\",\n    ) -> None:\n        image_path: Optional[Path] = None\n        thumbnail_path: Optional[Path] = None\n        image_existed = False\n        thumbnail_existed = False\n        try:\n            self.__validate_storage_folders()\n            image_path = self.get_path(image_name, image_subfolder=image_subfolder)","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_files/image_files_disk.py#L107-L143","documentation":"ImageFilesDisk.get() could not find the image file on disk when attempting to load a PIL image. The underlying FileNotFoundError is chained as the cause. This service is the storage layer for generated/uploaded images in InvokeAI, so the error means the requested image name/path does not resolve to an existing file.","triggerScenarios":"Calling get(image_name) (or indirectly via graph/workflow execution paths like get_workflow/get_graph) for an image whose file was deleted, never saved, or whose name/subfolder path does not exist under the output folder.","commonSituations":"Database record out of sync with disk (image deleted manually or by an external cleanup); images moved between flat/subfolder layouts after a migration; stale cache or board references pointing at removed files; interrupted staged deletes leaving records without files.","solutions":["Confirm the image file exists at the resolved path (get_path(image_name, ...)) and that image_name/subfolder are correct","Delete the stale image record via the API if the file is genuinely gone, so DB and disk re-sync","Check whether a staged delete committed while the record remained, and restore the file from backup if needed","Verify the output folder configuration points at the same directory used when the image was saved"],"exampleFix":"// before\nimage = services.images.get(image_name)\n// after\nfrom invokeai.app.services.images.images_common import ImageFileNotFoundException\ntry:\n    image = services.images.get(image_name)\nexcept ImageFileNotFoundException:\n    services.images.delete_image_on_record_missing(image_name)  # or handle gracefully","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\npath = services.images.get_path(image_name, image_subfolder=subfolder)\nif not Path(path).exists():\n    # record is stale; skip or clean up instead of loading\n    ...","typeGuard":null,"tryCatchPattern":"try:\n    image = services.images.get(image_name)\nexcept ImageFileNotFoundException:\n    logger.warning(f\"image file missing on disk: {image_name}\")\n    handle_missing_image(image_name)  # skip, regenerate, or purge the record","preventionTips":["Never delete files in the output folder outside the service's delete API","Periodically reconcile image DB records against disk contents","Use the service's stage/commit delete flow so records and files stay consistent","Keep output folder config stable across restarts/migrations"],"tags":["file-not-found","storage","image-files","disk"],"backgroundTag":"file-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}