invoke-ai/InvokeAI · error
Cross-filesystem image move is not supported: {source} -> {d
Error message
Cross-filesystem image move is not supported: {source} -> {destination} What it means
_assert_same_filesystem, called during preflight_moves, compares st_dev of the source directory and the nearest existing ancestor of the destination directory. If they differ, the move would cross filesystem boundaries (os.rename would fail with EXDEV), so the service raises ValueError('Cross-filesystem image move is not supported').
Source
Thrown at invokeai/app/services/image_moves/image_moves_default.py:876
self._fsync_dir(path.parent)
self.image_files.evict_cache_paths([old_path, new_path, old_thumbnail_path, new_thumbnail_path])
self.mark_item_moved(job_id, image_name)
def _remove_empty_parents(self, start: Path, root: Path) -> None:
root = root.resolve()
current = start.resolve()
while current != root and current.is_relative_to(root):
try:
current.rmdir()
except OSError:
return
current = current.parent
def _assert_same_filesystem(self, source: Path, destination: Path) -> None:
source_parent = source.parent
destination_parent = self._nearest_existing_parent(destination.parent)
if source_parent.stat().st_dev != destination_parent.stat().st_dev:
raise ValueError(f"Cross-filesystem image move is not supported: {source} -> {destination}")
def _nearest_existing_parent(self, path: Path) -> Path:
current = path
while not current.exists():
if current.parent == current:
raise FileNotFoundError(f"No existing parent found for {path}")
current = current.parent
return current
def _fsync_file(self, path: Path) -> None:
try:
with path.open("rb") as file:
os.fsync(file.fileno())
except OSError as e:
self._logger.debug("Unable to fsync file: %s: %s", path, e)
def _fsync_dir(self, path: Path) -> None:
try:View on GitHub (pinned to 0b6a024f2f)
Solutions
- Move the destination onto the same filesystem/mount as the source images directory (or vice versa).
- If using Docker/bind mounts, mount the destination path from the same volume as the images root.
- Replace a cross-device symlink with a same-filesystem directory or bind-mount the second disk into the tree so st_dev matches.
- Apply the subfolder strategy within the existing single filesystem instead of redirecting output to another device.
Example fix
// before # source: /srv/invokeai/images (dev 8:1) # destination: /mnt/nas/invokeai/images (dev 0:xx) -> ValueError // after: keep both on one filesystem ln -s /mnt/nas/invokeai /srv/invokeai/nas # NO - still cross-device for moves # instead mount nas under the same fs tree or move outputs dir onto /srv/invokeai
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def same_filesystem(src: Path, dst: Path) -> bool:
p = dst
while not p.exists():
p = p.parent
return os.stat(src.parent).st_dev == os.stat(p).st_dev Type guard
def paths_share_device(a: Path, b: Path) -> bool:
return a.stat().st_dev == b.stat().st_dev Try / catch
try:
service.preflight_moves(job_id)
except ValueError as e:
if "Cross-filesystem image move" in str(e):
# re-point destination onto the images filesystem or copy instead of move Prevention
- Keep the output/destination directory on the same mount as the images root
- In Docker, mount both paths from the same volume
- Avoid symlinked output folders on other devices
- Run preflight_moves and check st_dev early in setup scripts
When it happens
Trigger: Running preflight_moves where the images root and the destination subfolder root live on different mounts — e.g. destination on a NFS/network volume, separate SSD/HDD, tmpfs, or Docker bind mount not sharing a filesystem with the source.
Common situations: Docker container with images dir and output dir on different mounts; NAS mounts (NFS/SMB); symlinking an output folder to another disk; WSL/Windows drive boundaries (/mnt/c vs ~).
Related errors
- Source image does not exist: {move.old_path}
- Destination image already exists: {move.new_path}
- Destination thumbnail already exists: {move.new_thumbnail_pa
- Both old and new image files exist for {item.image_name}
- Neither old nor new image file exists for {item.image_name}
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/5234b8e251715099.
Report an issue: GitHub.