invoke-ai/InvokeAI · error · PermissionError

Queue user is not authorized to save images to this board

Error message

Queue user is not authorized to save images to this board

What it means

ImagesInterface.save throws PermissionError when a non-admin queue user tries to save to a board they neither own nor that is Public. Board ownership and visibility determine who may write images to it.

Source

Thrown at invokeai/app/services/shared/invocation_context.py:247

        if board_id:
            board_id_ = board_id
        elif isinstance(self._data.invocation, WithBoard) and self._data.invocation.board:
            board_id_ = self._data.invocation.board.board_id

        if self._services.configuration.multiuser:
            user = self._services.users.get(self._data.queue_item.user_id)
            # A deactivated or deleted account must not save outputs, even
            # uncategorized ones — deactivation revokes queue-time privileges.
            if user is None or not user.is_active:
                raise PermissionError("Queue user is not authorized to save images")
            if board_id_ is not None:
                board = self._services.boards.get_dto(board_id_)
                if (
                    not user.is_admin
                    and board.user_id != self._data.queue_item.user_id
                    and board.board_visibility != BoardVisibility.Public
                ):
                    raise PermissionError("Queue user is not authorized to save images to this board")

        workflow_ = None
        if self._data.queue_item.workflow:
            workflow_ = self._data.queue_item.workflow.model_dump_json()

        graph_ = None
        if self._data.queue_item.session.graph:
            graph_ = self._data.queue_item.session.graph.model_dump_json()

        return self._services.images.create(
            image=image,
            is_intermediate=self._data.invocation.is_intermediate,
            image_category=image_category,
            board_id=board_id_,
            metadata=metadata_,
            image_origin=ResourceOrigin.INTERNAL,
            workflow=workflow_,
            graph=graph_,

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Save to a board owned by the queue user (omit board_id to auto-create/own it)
  2. Use a Public board as the destination
  3. Have an admin run the workflow if the target board must stay private to its owner
  4. Catch PermissionError and fall back to saving without board_id

Example fix

# before
context.images.save(image, board_id=admins_private_board)
# after
user = services.users.get(context.queue_item.user_id)
board = services.boards.get_dto(board_id)
if user.is_admin or board.user_id == user.id or board.board_visibility == BoardVisibility.Public:
    context.images.save(image, board_id=board_id)
else:
    context.images.save(image)
Defensive patterns

Strategy: validation

Validate before calling

board = services.boards.get_dto(board_id)
user = services.users.get(queue_item.user_id)
if not (user.is_admin or board.user_id == queue_item.user_id or board.board_visibility == BoardVisibility.Public):
    raise SkipSave("board not writable by queue user")

Type guard

def can_write_board(services, queue_item, board_id: str) -> bool:
    user = services.users.get(queue_item.user_id)
    board = services.boards.get_dto(board_id)
    return bool(user and user.is_active) and (
        user.is_admin
        or board.user_id == queue_item.user_id
        or board.board_visibility == BoardVisibility.Public
    )

Try / catch

try:
    context.images.save(image, board_id=board_id)
except PermissionError:
    context.images.save(image)  # save without restricted board

Prevention

When it happens

Trigger: images.save(image, board_id=X) where the queue user is not admin, board X's user_id differs from queue_item.user_id, and board X's board_visibility is not Public.

Common situations: Workflow hardcoded with another user's board id; team deployments pointing shared workflows at a private admin board; copying board ids between user sessions.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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