invoke-ai/InvokeAI · error

Cannot create image move job while another active image move

Error message

Cannot create image move job while another active image move job exists

What it means

Only one image subfolder move job may be active at a time. Before inserting a new job row, create_move_job queries image_subfolder_move_jobs for any row whose state is not 'committed' or 'error' and refuses if one exists, protecting filesystem/DB consistency from concurrent moves.

Source

Thrown at invokeai/app/services/image_moves/image_moves_default.py:353

        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,
                    old_subfolder,
                    new_subfolder,
                    is_intermediate,
                    old_path,
                    new_path,
                    old_thumbnail_path,
                    new_thumbnail_path,
                    state
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'planned');
                """,
                [

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Let startup recovery (startup_recovery / complete_partial_filesystem_moves) finish or finalize the existing job before starting a new one
  2. Mark the stale job as 'error' or 'committed' once its outcome is known, then retry
  3. Poll job status and wait for state 'committed' or 'error' before scheduling another move
  4. Serialize move requests behind a lock/queue in the calling application

Example fix

// before
job_id = service.create_move_job(moves)
// after
if service.has_active_job():  # or check state via DB/API
    raise RuntimeError("wait for the current image move job to finish")
job_id = service.create_move_job(moves)
Defensive patterns

Strategy: validation

Validate before calling

active = db.query("SELECT 1 FROM image_subfolder_move_jobs WHERE state NOT IN ('committed','error') LIMIT 1").fetchone()
if active:
    raise RuntimeError("another image move job is active")
service.create_move_job(moves)

Type guard

def can_start_job(state: str | None) -> bool:
    return state in (None, "committed", "error")

Try / catch

try:
    job_id = service.create_move_job(moves)
except ValueError as e:
    if "another active image move job" in str(e):
        wait_for_job_completion()  # poll states
        job_id = service.create_move_job(moves)
    else:
        raise

Prevention

When it happens

Trigger: Calling create_move_job (or move_all_images) while a previous job is in state 'planned' or 'running' — e.g. a prior move crashed mid-way, or two API requests/schedulers start moves concurrently.

Common situations: App restart while a move job was in progress (job left in non-terminal state); double-clicking a 'move' button firing two requests; scheduled task overlapping a long-running manual move.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/706b280464cb3f17. Report an issue: GitHub.