{"record":{"id":"05a61e180dbd26f4","repo":"invoke-ai/InvokeAI","slug":"source-image-does-not-exist-move-old-path","errorCode":null,"errorMessage":"Source image does not exist: {move.old_path}","messagePattern":"Source image does not exist: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_moves/image_moves_default.py","lineNumber":432,"sourceCode":"                    move.old_subfolder,\n                    move.new_subfolder,\n                    int(move.is_intermediate),\n                    str(move.old_path),\n                    str(move.new_path),\n                    str(move.old_thumbnail_path),\n                    str(move.new_thumbnail_path),\n                    message,\n                ),\n            )\n            return job_id\n\n    def preflight_moves(self, moves: Sequence[PlannedImageMove]) -> None:\n        destinations: set[Path] = set()\n        thumbnail_destinations: set[Path] = set()\n        for move in moves:\n            if not move.old_path.exists():\n                if not move.is_intermediate:\n                    raise FileNotFoundError(f\"Source image does not exist: {move.old_path}\")\n                continue\n            if move.new_path.exists():\n                raise FileExistsError(f\"Destination image already exists: {move.new_path}\")\n            if move.old_path == move.new_path:\n                raise ValueError(f\"Old and new paths are identical for {move.image_name}\")\n            if move.new_path in destinations:\n                raise ValueError(f\"Duplicate destination path: {move.new_path}\")\n            destinations.add(move.new_path)\n            if move.new_thumbnail_path in thumbnail_destinations:\n                raise ValueError(f\"Duplicate destination thumbnail path: {move.new_thumbnail_path}\")\n            thumbnail_destinations.add(move.new_thumbnail_path)\n            if self._has_active_job_for_image(move.image_name):\n                raise ValueError(f\"Image {move.image_name} already has an active image move job\")\n            self._assert_same_filesystem(move.old_path, move.new_path)\n            if move.old_thumbnail_path.exists():\n                if move.new_thumbnail_path.exists():\n                    raise FileExistsError(f\"Destination thumbnail already exists: {move.new_thumbnail_path}\")\n                self._assert_same_filesystem(move.old_thumbnail_path, move.new_thumbnail_path)","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_moves/image_moves_default.py#L414-L450","documentation":"preflight_moves validates each planned move before any files are touched. If the source image file does not exist and the move is not marked intermediate, it raises FileNotFoundError naming the path. Intermediates are allowed to be missing (they may not have been written yet); regular images are not.","triggerScenarios":"Planning a move for an image whose file was deleted from disk after being registered in the DB; wrong images root configured so paths don't resolve; calling preflight_moves/_plan_batch for an image on a detached/unmounted volume.","commonSituations":"Manual deletion or external sync tool removing files while InvokeAI's DB still lists them; misconfigured output/inputs directory; restoring the DB without restoring the file tree.","solutions":["Restore the missing file or delete the stale DB record, then re-plan","Set is_intermediate on the PlannedImageMove if the file legitimately may not exist yet","Verify the configured images root/path resolution matches where files actually live","Filter out moves with nonexistent sources in the caller before planning"],"exampleFix":"// before\nmoves = [PlannedImageMove(image_name=n, old_path=p, new_path=q, is_intermediate=False)]\nservice.preflight_moves(moves)\n// after\nmoves = [PlannedImageMove(image_name=n, old_path=p, new_path=q, is_intermediate=not p.exists())]\nservice.preflight_moves(moves)","handlingStrategy":"validation","validationCode":"missing = [m for m in moves if not m.old_path.exists() and not m.is_intermediate]\nif missing:\n    raise FileNotFoundError(f\"sources missing: {[str(m.old_path) for m in missing]}\")\nservice.preflight_moves(moves)","typeGuard":"def source_exists(move: PlannedImageMove) -> bool:\n    return move.is_intermediate or move.old_path.exists()","tryCatchPattern":"try:\n    service.preflight_moves(moves)\nexcept FileNotFoundError as e:\n    reconcile_db_with_disk(str(e))  # repair stale records or restore files","preventionTips":["Keep the images DB in sync with the filesystem (avoid manual deletions)","Verify the configured images root before planning moves","Mark genuinely optional files as intermediate"],"tags":["filesystem","file-not-found","image-move","preflight"],"backgroundTag":"file-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}