invoke-ai/InvokeAI · error · WorkflowNotFoundError

Workflow with id {workflow_id} not found

Error message

Workflow with id {workflow_id} not found

What it means

WorkflowRecordsSQLite.get raises WorkflowNotFoundError when no row with the given workflow_id exists in the workflow_library table. Many public methods (create, update, delete, update_is_public, _sync_default_workflows) call get internally, so this error surfaces from those too when operating on a nonexistent or already-deleted workflow.

Source

Thrown at invokeai/app/services/workflow_records/workflow_records_sqlite.py:48

    def start(self, invoker: Invoker) -> None:
        self._invoker = invoker
        self._sync_default_workflows()

    def get(self, workflow_id: str) -> WorkflowRecordDTO:
        """Gets a workflow by ID. Updates the opened_at column."""
        with self._db.transaction() as cursor:
            cursor.execute(
                """--sql
                SELECT workflow_id, workflow, name, created_at, updated_at, opened_at, user_id, is_public
                FROM workflow_library
                WHERE workflow_id = ?;
                """,
                (workflow_id,),
            )
            row = cursor.fetchone()
        if row is None:
            raise WorkflowNotFoundError(f"Workflow with id {workflow_id} not found")
        return WorkflowRecordDTO.from_dict(dict(row))

    def create(
        self,
        workflow: WorkflowWithoutID,
        user_id: str = WORKFLOW_LIBRARY_DEFAULT_USER_ID,
        is_public: bool = False,
    ) -> WorkflowRecordDTO:
        if workflow.meta.category is WorkflowCategory.Default:
            raise ValueError("Default workflows cannot be created via this method")

        with self._db.transaction() as cursor:
            workflow_with_id = Workflow(**workflow.model_dump(), id=uuid_string())
            cursor.execute(
                """--sql
                INSERT OR IGNORE INTO workflow_library (
                    workflow_id,
                    workflow,

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the workflow_id exists (query the workflow library UI or SELECT from workflow_library) before mutating
  2. Catch WorkflowNotFoundError and refresh the client's workflow list
  3. If DB was reset, re-import the workflow instead of referencing the old id

Example fix

# before
record = service.update(Workflow(id="abc-123", ...))
# after
try:
    record = service.update(Workflow(id="abc-123", ...))
except WorkflowNotFoundError:
    record = service.create(WorkflowWithoutID(**workflow.model_dump(exclude={"id"})))
Defensive patterns

Strategy: try-catch

Validate before calling

def workflow_exists(service, workflow_id: str) -> bool:
    try:
        service.get(workflow_id)
        return True
    except WorkflowNotFoundError:
        return False

Try / catch

try:
    record = service.update(workflow)
except WorkflowNotFoundError:
    logger.info("workflow %s missing, recreating", workflow.id)
    record = service.create(WorkflowWithoutID(**workflow.model_dump(exclude={"id"})))

Prevention

When it happens

Trigger: get(id) with a stale/typo'd UUID; update/delete/update_is_public on a workflow deleted in another session; calling create with an id collision path that then re-gets a purged row.

Common situations: Client caches holding workflow ids after a DB reset or migration; shared databases where another user deleted the workflow; restoring old workflow JSON with ids from a wiped database.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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