invoke-ai/InvokeAI · warning · HTTPException

Not authorized to delete this board

Error message

Not authorized to delete this board

What it means

HTTP 403 raised by the delete_board endpoint when the authenticated user is neither an admin nor the owner of the board (board.user_id != current_user.user_id). The InvokeAI API enforces ownership on destructive board operations; only admins or the creating user may delete a board.

Source

Thrown at invokeai/app/api/routers/boards.py:136

        raise HTTPException(status_code=500, detail="Failed to update board")


@boards_router.delete("/{board_id}", operation_id="delete_board", response_model=DeleteBoardResult)
def delete_board(
    current_user: CurrentUserOrDefault,
    board_id: str = Path(description="The id of board to delete"),
    include_images: Optional[bool] = Query(
        description="Permanently delete all images and videos on the board", default=False
    ),
) -> DeleteBoardResult:
    """Deletes a board (user must have access to it)"""
    try:
        board = ApiDependencies.invoker.services.boards.get_dto(board_id=board_id)
    except Exception:
        raise HTTPException(status_code=404, detail="Board not found")

    if not current_user.is_admin and board.user_id != current_user.user_id:
        raise HTTPException(status_code=403, detail="Not authorized to delete this board")

    # Admins delete everything on the board; regular owners only delete their own
    # contributions so that contributions from other users to a public/shared board
    # are preserved (they cascade to "uncategorized" via FK on board_videos / board_images).
    cascade_user_id: Optional[str] = None if current_user.is_admin else current_user.user_id
    deleted_images: list[str] = []
    deleted_videos: list[str] = []

    try:
        if include_images is True:
            assert_image_move_maintenance_inactive()
            # The services report both outcomes: records whose file delete failed are
            # preserved (they cascade to "uncategorized" via the board FKs when the
            # board is deleted below) and returned as failures. This is the ground
            # truth — reconstructing failures by diffing a router-side board listing
            # against the deleted names would double the DB work and misreport items
            # moved or deleted concurrently between the two queries.
            deleted_images, failed_images = ApiDependencies.invoker.services.images.delete_images_on_board(

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Delete the board as the owning user or an admin account
  2. Verify current_user.user_id matches board.user_id (fetch the board DTO first to check ownership)
  3. If the board should be shared-deletable, promote the account to admin or transfer ownership of the board

Example fix

// before: deleting as another user
deleteBoard(boardId); // 403 Not authorized
// after: check ownership client-side before calling
const board = await getBoard(boardId);
if (board.user_id === currentUser.user_id || currentUser.is_admin) {
  await deleteBoard(boardId);
}
Defensive patterns

Strategy: validation

Validate before calling

const board = await getBoard(boardId);
if (!(currentUser.is_admin || board.user_id === currentUser.user_id)) {
  throw new Error('Skipping delete: not the board owner');
}

Type guard

const canDeleteBoard = (board, user) =>
  Boolean(user?.is_admin) || board?.user_id === user?.user_id;

Try / catch

try {
  await api.delete(`/boards/${boardId}`);
} catch (e) {
  if (e.response?.status === 403) notify('Only the board owner or an admin can delete this board');
  else throw e;
}

Prevention

When it happens

Trigger: Calling DELETE on a board whose DTO's user_id differs from the JWT/session user's id while current_user.is_admin is false.

Common situations: Two users on the same InvokeAI instance sharing boards; a stale token or admin-downgraded account operating on another user's board; automated scripts reusing credentials of a non-owner user.

Related errors


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