invoke-ai/InvokeAI · error

Image move job {job_id} failed commit validation

Error message

Image move job {job_id} failed commit validation

What it means

Raised by commit_database_updates after running an internal SQL consistency check: if any image_subfolder_move_items rows for the job are in an invalid/inconsistent state (e.g. moved files on disk that don't match the expected pre-commit state), the job fails commit validation and the database update is aborted. This protects against committing a DB state that doesn't match the filesystem.

Source

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

            )
            cursor.execute(
                """--sql
                SELECT COUNT(*)
                FROM image_subfolder_move_items AS item
                LEFT JOIN images ON images.image_name = item.image_name
                WHERE item.job_id = ?
                  AND item.state = 'moved'
                  AND (
                    images.image_name IS NULL
                    OR images.deleted_at IS NOT NULL
                    OR images.image_subfolder != item.new_subfolder
                  );
                """,
                (job_id,),
            )
            invalid_count = cast(int, cursor.fetchone()[0])
            if invalid_count:
                raise RuntimeError(f"Image move job {job_id} failed commit validation")
            cursor.execute(
                "SELECT COUNT(*) FROM image_subfolder_move_items WHERE job_id = ? AND state = 'moved';",
                (job_id,),
            )
            moved_count = cast(int, cursor.fetchone()[0])
            cursor.execute(
                """--sql
                SELECT error_message
                FROM image_subfolder_move_items
                WHERE job_id = ? AND state = 'error'
                ORDER BY image_name;
                """,
                (job_id,),
            )
            error_rows = cursor.fetchall()
            error_messages = [cast(str, row[0]) for row in error_rows if row[0]]
            cursor.execute(
                "UPDATE image_subfolder_move_items SET state = 'committed' WHERE job_id = ? AND state = 'moved';",

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Query image_subfolder_move_items for the job and inspect state values to find the invalid rows: SELECT image_name, state FROM image_subfolder_move_items WHERE job_id = ? AND state NOT IN ('moved','skipped','failed');
  2. Re-run startup_recovery so the filesystem and item states are re-reconciled before commit.
  3. Fix item states to terminal values only after verifying the actual file locations on disk.
  4. If the job is hopelessly inconsistent, reset items to 'planned' and re-plan the move after confirming the current file layout.

Example fix

// before: commit aborts due to non-terminal item states
sqlite3 invokeai.db "SELECT image_name,state FROM image_subfolder_move_items WHERE job_id=3;"
// after: reconcile, then mark verified rows terminal
sqlite3 invokeai.db "UPDATE image_subfolder_move_items SET state='moved' WHERE job_id=3 AND image_name='a.png';"
# re-run startup_recovery then commit_database_updates
Defensive patterns

Strategy: try-catch

Validate before calling

import sqlite3
def job_is_consistent(db_path: str, job_id: int) -> bool:
    con = sqlite3.connect(db_path)
    n = con.execute(
        "SELECT COUNT(*) FROM image_subfolder_move_items WHERE job_id=? AND state NOT IN ('moved','skipped','failed')",
        (job_id,),
    ).fetchone()[0]
    return n == 0

Type guard

def item_state_is_terminal(state: str) -> bool:
    return state in {'moved', 'skipped', 'failed'}

Try / catch

try:
    service.commit_database_updates(job_id)
except RuntimeError as e:
    if "failed commit validation" in str(e):
        # reconcile filesystem vs DB via startup_recovery, then retry once
        service.startup_recovery()
        service.commit_database_updates(job_id)

Prevention

When it happens

Trigger: move_all_images or startup_recovery reaching the commit phase while item rows are in an unexpected state — typically because filesystem completion (_complete_partial_filesystem_move) failed partway, items were manually modified in the DB, or a previous crashed commit left rows half-updated.

Common situations: Interrupted earlier recovery run; manual DB edits; concurrent move jobs touching the same items; a prior item-level error (e.g. unreadable image) leaving items non-terminal.

Related errors


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