{"record":{"id":"cbf4a60ccf791670","repo":"invoke-ai/InvokeAI","slug":"neither-old-nor-new-image-file-exists-for-item-im","errorCode":null,"errorMessage":"Neither old nor new image file exists for {item.image_name}","messagePattern":"Neither old nor new image file exists for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_moves/image_moves_default.py","lineNumber":511,"sourceCode":"        new_thumbnail_path = self.image_files.get_path(\n            item.image_name, thumbnail=True, image_subfolder=item.new_subfolder\n        )\n        old_exists = old_path.exists()\n        new_exists = new_path.exists()\n        if old_exists and new_exists:\n            raise RuntimeError(f\"Both old and new image files exist for {item.image_name}\")\n        if not old_exists and not new_exists:\n            if item.is_intermediate:\n                self._mark_missing_intermediate_moved(\n                    job_id=job_id,\n                    image_name=item.image_name,\n                    old_path=old_path,\n                    new_path=new_path,\n                    old_thumbnail_path=old_thumbnail_path,\n                    new_thumbnail_path=new_thumbnail_path,\n                )\n                return\n            raise RuntimeError(f\"Neither old nor new image file exists for {item.image_name}\")\n\n        old_thumbnail_exists = old_thumbnail_path.exists()\n        new_thumbnail_exists = new_thumbnail_path.exists()\n        if (\n            old_exists\n            and not new_exists\n            and (\n                (not old_thumbnail_exists and not new_thumbnail_exists)\n                or (old_thumbnail_exists and new_thumbnail_exists)\n            )\n        ):\n            # Generate the thumbnail while the source is still available. If this fails,\n            # leave the source untouched so transient failures can be retried and corrupt\n            # images can be repaired or removed by the operator.\n            self._regenerate_thumbnail(old_path, new_thumbnail_path)\n\n        if not old_exists and new_exists and not old_thumbnail_exists and not new_thumbnail_exists:\n            self._regenerate_thumbnail(new_path, new_thumbnail_path)","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_moves/image_moves_default.py#L493-L529","documentation":"Raised by _complete_partial_filesystem_move when neither the old nor the new image file exists for an item being completed. The move record says there should be a file in one of the two locations, but the underlying image has vanished, so completion cannot proceed for non-intermediate images (intermediates are tolerated via _mark_missing_intermediate_moved).","triggerScenarios":"complete_partial_filesystem_moves processing an item whose image was deleted from disk (manually, by a cleanup job, or by a failed earlier move that removed the source before writing the destination), or an incorrect new_subfolder recorded in the DB pointing at the wrong folder.","commonSituations":"User deleted images directly on disk while a move job was pending; disk/restore lost files; intermediates cleanup raced with a move job; DB rows referencing images removed by 'Delete all images' during a pending move.","solutions":["Confirm the image is truly gone (search all subfolders for the image_name); if found, move it to the expected old or new path and re-run recovery.","If the image is intentionally deleted, delete the corresponding image_subfolder_move_items row (and image DB record) so completion no longer expects the file.","For intermediates, verify the is_intermediate flag is set correctly; missing intermediates are tolerated and marked moved automatically.","Check for case-sensitivity or subfolder naming mismatches between DB old_subfolder/new_subfolder and the on-disk layout."],"exampleFix":"// before: DB row expects file that was deleted\nSELECT image_name FROM image_subfolder_move_items WHERE job_id = 7 AND state = 'planned';\n// after: remove orphaned item for intentionally deleted image\nDELETE FROM image_subfolder_move_items WHERE job_id = 7 AND image_name = 'missing.png';\nDELETE FROM images WHERE image_name = 'missing.png';","handlingStrategy":"validation","validationCode":"from pathlib import Path\ndef item_file_missing(item) -> bool:\n    return not item.old_path.exists() and not item.new_path.exists()\n# pre-check each planned item before completing","typeGuard":"def file_available(paths: list[Path]) -> bool:\n    return any(p.exists() for p in paths)","tryCatchPattern":"try:\n    service.complete_partial_filesystem_moves(job_id)\nexcept RuntimeError as e:\n    if \"Neither old nor new image file exists\" in str(e):\n        # image gone: drop the item/record instead of retrying\n        ...","preventionTips":["Don't delete images from disk while a move job is planned/in-progress","Run move jobs when no bulk-delete operations are queued","Check that pending move items reference existing files before completing","Use the app's delete APIs so DB records and pending items stay consistent"],"tags":["filesystem","image-move","missing-file","runtime"],"backgroundTag":"file-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}