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
- Verify the board_id is correct — list boards via GET /v1/boards/ and use an existing ID
- Recreate the board if it was deleted; references to it cannot be restored automatically
- Refresh the UI so it re-fetches the board list and drops stale references
- 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
- Never hard-code board IDs; look them up by name at runtime
- Refresh board lists after deletes and on app start
- Handle 404 by re-selecting a board rather than retrying the same ID
- If a valid board returns 404 unexpectedly, check server logs — the route maps all lookup exceptions to 404
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
- Image not found
- Board not found
- str(e) (ValueError, relationship not found)
- Style preset not found
- System prompt not found
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/dcb7ece7cce23c7c.
Report an issue: GitHub.