invoke-ai/InvokeAI · error
Destination image already exists: {move.new_path}
Error message
Destination image already exists: {move.new_path} What it means
preflight_moves raises FileExistsError when the destination image path already exists on disk, preventing an overwrite of user data by the move operation. The check runs only when the source exists, and before the move is recorded.
Source
Thrown at invokeai/app/services/image_moves/image_moves_default.py:435
str(move.old_path),
str(move.new_path),
str(move.old_thumbnail_path),
str(move.new_thumbnail_path),
message,
),
)
return job_id
def preflight_moves(self, moves: Sequence[PlannedImageMove]) -> None:
destinations: set[Path] = set()
thumbnail_destinations: set[Path] = set()
for move in moves:
if not move.old_path.exists():
if not move.is_intermediate:
raise FileNotFoundError(f"Source image does not exist: {move.old_path}")
continue
if move.new_path.exists():
raise FileExistsError(f"Destination image already exists: {move.new_path}")
if move.old_path == move.new_path:
raise ValueError(f"Old and new paths are identical for {move.image_name}")
if move.new_path in destinations:
raise ValueError(f"Duplicate destination path: {move.new_path}")
destinations.add(move.new_path)
if move.new_thumbnail_path in thumbnail_destinations:
raise ValueError(f"Duplicate destination thumbnail path: {move.new_thumbnail_path}")
thumbnail_destinations.add(move.new_thumbnail_path)
if self._has_active_job_for_image(move.image_name):
raise ValueError(f"Image {move.image_name} already has an active image move job")
self._assert_same_filesystem(move.old_path, move.new_path)
if move.old_thumbnail_path.exists():
if move.new_thumbnail_path.exists():
raise FileExistsError(f"Destination thumbnail already exists: {move.new_thumbnail_path}")
self._assert_same_filesystem(move.old_thumbnail_path, move.new_thumbnail_path)
def _record_missing_source_errors(self, moves: Sequence[PlannedImageMove]) -> tuple[list[PlannedImageMove], int]:
remaining_moves: list[PlannedImageMove] = []View on GitHub (pinned to 0b6a024f2f)
Solutions
- Run startup_recovery/complete_partial_filesystem_moves to finish or reconcile the earlier job instead of re-planning
- Choose a different destination subfolder or rename to avoid the collision
- Remove or rename the pre-existing destination file if it is safe to discard
- Detect and skip already-moved images in the caller before planning
Example fix
// before
service.preflight_moves(moves) # FileExistsError
// after
moves = [m for m in moves if not m.new_path.exists()]
if moves:
service.preflight_moves(moves) Defensive patterns
Strategy: validation
Validate before calling
conflicts = [m for m in moves if m.old_path.exists() and m.new_path.exists()]
if conflicts:
raise FileExistsError(f"destinations exist: {[str(m.new_path) for m in conflicts]}")
service.preflight_moves(moves) Type guard
def destination_free(move: PlannedImageMove) -> bool:
return not move.new_path.exists() Try / catch
try:
service.preflight_moves(moves)
except FileExistsError as e:
run_startup_recovery_or_choose_new_destination(e) Prevention
- Reconcile partially-completed moves via recovery instead of blind retries
- Check destination occupancy before choosing target folders
- Be careful with case-insensitive filesystems when generating names
When it happens
Trigger: Re-running a move after a previous run already copied/moved files to the destination; two images resolving to the same destination name via path collisions; destination folder seeded externally with same-named files.
Common situations: Retrying a partially-completed move without recovery; importing images into a folder that already contains same-named outputs; case-insensitive filesystems colliding names that differ only by case.
Related errors
- Source image does not exist: {move.old_path}
- Destination thumbnail already exists: {move.new_thumbnail_pa
- [Errno 17] File {job.download_path} exists
- Old and new paths are identical for {move.image_name}
- Duplicate destination path: {move.new_path}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/15367db10c5eeb48.
Report an issue: GitHub.