invoke-ai/InvokeAI · error
Both old and new image files exist for {item.image_name}
Error message
Both old and new image files exist for {item.image_name} What it means
Raised by _complete_partial_filesystem_move when, before committing a batch image move, both the old and new image file paths exist on disk. This is an ambiguous state — the move may have been partially executed plus a duplicate copy left behind — so the code refuses to guess which file is authoritative and aborts that item with a RuntimeError instead of silently overwriting data.
Source
Thrown at invokeai/app/services/image_moves/image_moves_default.py:499
if not self._is_unrecoverable_error(e):
raise
self._reconcile_destination_subfolder(item)
self.mark_item_unrecoverable(job_id, item.image_name, f"{item.image_name}: {e}")
self._logger.error("Image move skipped unrecoverable item %s: %s", item.image_name, e)
def _complete_partial_filesystem_move(self, job_id: int, item: PlannedImageMove) -> None:
old_path = self.image_files.get_path(item.image_name, image_subfolder=item.old_subfolder)
new_path = self.image_files.get_path(item.image_name, image_subfolder=item.new_subfolder)
old_thumbnail_path = self.image_files.get_path(
item.image_name, thumbnail=True, image_subfolder=item.old_subfolder
)
new_thumbnail_path = self.image_files.get_path(
item.image_name, thumbnail=True, image_subfolder=item.new_subfolder
)
old_exists = old_path.exists()
new_exists = new_path.exists()
if old_exists and new_exists:
raise RuntimeError(f"Both old and new image files exist for {item.image_name}")
if not old_exists and not new_exists:
if item.is_intermediate:
self._mark_missing_intermediate_moved(
job_id=job_id,
image_name=item.image_name,
old_path=old_path,
new_path=new_path,
old_thumbnail_path=old_thumbnail_path,
new_thumbnail_path=new_thumbnail_path,
)
return
raise RuntimeError(f"Neither old nor new image file exists for {item.image_name}")
old_thumbnail_exists = old_thumbnail_path.exists()
new_thumbnail_exists = new_thumbnail_path.exists()
if (
old_exists
and not new_existsView on GitHub (pinned to 0b6a024f2f)
Solutions
- Manually inspect and delete the stale duplicate (usually the old-path copy is the leftover; verify checksums against the DB record first) then re-run startup_recovery / complete_partial_filesystem_moves.
- Check job item state in image_subfolder_move_items; if the item is already 'moved', remove the duplicate old file rather than re-running the move.
- If the new file is corrupt/truncated from an interrupted copy, delete the new file so only old_exists and let the move re-execute.
- Restore the directory from backup to a consistent single-copy state, then re-run the move job.
Example fix
// before (ambiguous state, move aborts) # images/old/abc.png AND images/new/abc.png both present // after (resolve duplicate, keep the verified good copy) # verify checksums, then: rm images/old/abc.png rm images/old/abc.webp # stale thumbnail if present # re-run recovery invokeai-move-recovery # or service.complete_partial_filesystem_moves(job_id)
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
old = Path(old_subfolder_dir) / image_name
new = Path(new_subfolder_dir) / image_name
if old.exists() and new.exists():
raise RuntimeError(f"resolve duplicate before completing move: {image_name}") Type guard
def has_no_duplicate_move(old: Path, new: Path) -> bool:
return not (old.exists() and new.exists()) Try / catch
try:
service.complete_partial_filesystem_moves(job_id)
except RuntimeError as e:
if "Both old and new image files exist" in str(e):
# resolve the duplicate manually, then re-run
... Prevention
- Never manually copy images back into their source subfolder while a move job is pending
- Let startup_recovery run after any crash before issuing new move jobs
- Verify job state via get_job before re-running moves
- Avoid running concurrent move jobs on the same images root
When it happens
Trigger: Completing a partially-applied subfolder move (complete_partial_filesystem_moves) where a previous run already copied/moved the image to item.new_subfolder but the source at old_subfolder was not removed (e.g. a crash between copy and delete, or a manual re-copy of the file into the old location).
Common situations: Crash or power loss mid-move leaving duplicate files; a user manually copying the image back to its original folder after a partial move; running the move job twice with a strategy that resolved the same destination; backups/restores that recreate the old path.
Related errors
- Neither old nor new image file exists for {item.image_name}
- Source image does not exist: {move.old_path}
- Destination image already exists: {move.new_path}
- Destination thumbnail already exists: {move.new_thumbnail_pa
- Image move job {job_id} has no items
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/0e13ae632ed93993.
Report an issue: GitHub.