invoke-ai/InvokeAI · error · HTTPException

Board not found

Error message

Board not found

What it means

`assert_board_read_access` raises this 404 when the board DTO cannot be fetched from the boards service. Any exception during lookup — most commonly a nonexistent board_id — is translated into 'Board not found', so callers get a 404 rather than a 500 or a misleading 403.

Source

Thrown at invokeai/app/api/routers/_access.py:129

    _assert_image_record_exists(image_name)
    raise HTTPException(status_code=403, detail="Not authorized to access this image")


def assert_board_read_access(board_id: str, current_user: CurrentUserOrDefault) -> None:
    """Raise 403 if the current user may not read images from this board.

    Access is granted when ANY of these hold:
    - The user is an admin.
    - The user owns the board.
    - The board visibility is Shared or Public.
    """
    if current_user.is_admin:
        return

    try:
        board = ApiDependencies.invoker.services.boards.get_dto(board_id=board_id)
    except Exception:
        raise HTTPException(status_code=404, detail="Board not found")

    if board.user_id == current_user.user_id:
        return

    if board.board_visibility in (BoardVisibility.Shared, BoardVisibility.Public):
        return

    raise HTTPException(status_code=403, detail="Not authorized to access this board")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Verify the board_id is correct — list boards via GET /v1/boards/ and use an existing ID
  2. Recreate the board if it was deleted; references to it cannot be restored automatically
  3. Refresh the UI so it re-fetches the board list and drops stale references
  4. If the board should exist and you suspect a storage error, check server logs/DB health — the blanket except can mask real failures

Example fix

// before
await fetch(`/v1/boards/${hardcodedBoardId}`); // 404
// after
const boards = await fetch('/v1/boards/').then(r => r.json());
const id = boards.items.find(b => b.board_name === 'My Board').board_id;
await fetch(`/v1/boards/${id}`);
Defensive patterns

Strategy: try-catch

Validate before calling

// Resolve board_id from the live board list instead of caching it
const boards = await fetch('/v1/boards/', {headers: authHeaders}).then(r => r.json());
if (!boards.items.some(b => b.board_id === boardId)) throw new Error(`Board ${boardId} no longer exists`);

Try / catch

try {
  const board = await fetch(`/v1/boards/${boardId}`, {headers: authHeaders});
  if (board.status === 404) throw new NotFoundError(boardId);
  return await board.json();
} catch (e) {
  if (e instanceof NotFoundError) refreshBoardList(); // drop stale ID, re-select
  else throw e;
}

Prevention

When it happens

Trigger: GET on board or board-images endpoints (/v1/boards/{board_id}, /v1/board_images/{board_id}) with a board_id absent from the database; also fires on storage errors during lookup because all exceptions are caught.

Common situations: A UI tab still open after the board was deleted; a hard-coded or copied board ID from another instance; a corrupted/transient database failure being masked as not-found.

Related errors


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