invoke-ai/InvokeAI · error
Cannot create an image move job with no items
Error message
Cannot create an image move job with no items
What it means
create_move_job refuses to insert an image_subfolder_move_jobs row when the planned moves list is empty. An empty job would have no items to move, so the service treats it as a programming/caller mistake rather than a silent no-op. It is raised before any DB transaction begins.
Source
Thrown at invokeai/app/services/image_moves/image_moves_default.py:342
old_path=self.image_files.get_path(image_name, image_subfolder=old_subfolder),
new_path=self.image_files.get_path(image_name, image_subfolder=new_subfolder),
old_thumbnail_path=self.image_files.get_path(
image_name, thumbnail=True, image_subfolder=old_subfolder
),
new_thumbnail_path=self.image_files.get_path(
image_name, thumbnail=True, image_subfolder=new_subfolder
),
)
)
errors = 0
if record_missing_errors:
moves, errors = self._record_missing_source_errors(moves)
self.preflight_moves(moves)
return moves, errors
def create_move_job(self, moves: Sequence[PlannedImageMove]) -> int:
if not moves:
raise ValueError("Cannot create an image move job with no items")
with self._db.transaction() as cursor:
cursor.execute(
"""--sql
SELECT 1
FROM image_subfolder_move_jobs
WHERE state NOT IN ('committed', 'error')
LIMIT 1;
"""
)
if cursor.fetchone() is not None:
raise ValueError("Cannot create image move job while another active image move job exists")
cursor.execute("INSERT INTO image_subfolder_move_jobs (state) VALUES ('planned');")
job_id = cast(int, cursor.lastrowid)
cursor.executemany(
"""--sql
INSERT INTO image_subfolder_move_items (
job_id,
image_name,View on GitHub (pinned to 0b6a024f2f)
Solutions
- Check that the moves list has at least one PlannedImageMove before calling create_move_job, or return early/raise a friendlier error in the caller
- In move_all_images, skip job creation when planning returns zero moves (optionally reporting 'nothing to move')
- Verify preflight/record_missing_source_errors filtering isn't unexpectedly dropping all moves
Example fix
// before
moves, errors = planner.plan(...)
job_id = service.create_move_job(moves)
// after
moves, errors = planner.plan(...)
if not moves:
return # or raise ValueError(f"nothing to move ({errors} errors)")
job_id = service.create_move_job(moves) Defensive patterns
Strategy: validation
Validate before calling
if not moves:
raise ValueError("refusing to create an image move job with no items")
service.create_move_job(moves) Type guard
def has_moves(moves: Sequence[PlannedImageMove]) -> bool:
return len(moves) > 0 Try / catch
try:
job_id = service.create_move_job(moves)
except ValueError as e:
if "no items" in str(e):
log.info("nothing to move; skipping job creation")
job_id = None
else:
raise Prevention
- Early-return in callers when planning yields zero moves
- Count filtered/errored moves so silent filtering can't empty the batch unnoticed
- Unit-test the empty-batch path of any move orchestration code
When it happens
Trigger: Calling create_move_job([]) directly, or calling move_all_images/_plan_batch when _record_missing_source_errors filtered out every move (e.g. all sources already missing and counted as errors) so an empty list reaches this method.
Common situations: Batch scripts selecting an empty subfolder; UI invoking 'move all' on a folder with no images; after a previous run already removed/errored all candidate images so planning yields zero moves.
Related errors
- Old and new paths are identical for {move.image_name}
- Duplicate destination path: {move.new_path}
- Duplicate destination thumbnail path: {move.new_thumbnail_pa
- Unknown image subfolder strategy: {strategy}
- encode_caption_for_pid requires at least one caption.
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/51760efee900c761.
Report an issue: GitHub.