invoke-ai/InvokeAI · error · HTTPException
Failed to remove images from board
Error message
Failed to remove images from board
What it means
HTTP 500 raised by POST /board_images/batch/delete (remove_images_from_board) on any unexpected exception in the bulk removal path. Expected per-image misses are collected into failed_images; only service/DB level failures reach this generic handler.
Source
Thrown at invokeai/app/api/routers/board_images.py:435
affected_boards.add(old_board_id)
elif outcome is _ScopedRemoveOutcome.MOVED:
failed_images.add(image_name)
# GONE: a skip, exactly as the gone-block above treats a name that vanished
# before the loop reached it.
except Exception:
# A genuine storage failure, not an auth/404 skip — see add_images_to_board.
# The zero-row classification's own reads land here too: a name whose state
# cannot be decided is reported, never dropped.
failed_images.add(image_name)
return RemoveImagesFromBoardResult(
removed_images=list(removed_images),
failed_images=list(failed_images),
affected_boards=list(affected_boards),
)
except HTTPException:
raise
except Exception:
raise HTTPException(status_code=500, detail="Failed to remove images from board")
View on GitHub (pinned to 0b6a024f2f)
Solutions
- Read the server-side traceback for the root cause
- Confirm the board still exists before batch delete
- Split large batches into smaller chunks to avoid lock timeouts
- Check DB health (locks, connections, disk)
- Retry idempotently — already-removed images are reported, not fatal
Example fix
// before
await api.post('/board_images/batch/delete', { image_names: all, board_id });
// after
for (const chunk of chunks(all, 50)) {
await api.post('/board_images/batch/delete', { image_names: chunk, board_id });
} Defensive patterns
Strategy: retry
Validate before calling
const board = await api.get(`/boards/${boardId}`).catch(() => null);
if (!board) throw new Error(`Board ${boardId} missing; skip batch delete`); Type guard
const isServerError = (e) => e?.response?.status >= 500;
Try / catch
try {
await api.post('/board_images/batch/delete', { image_names, board_id });
} catch (e) {
if (isServerError(e)) await sleep(1000 * attempt); // then retry chunk
throw e;
} Prevention
- Split large batches into chunks (e.g. 50) to dodge DB lock timeouts
- Retry idempotently — already-removed images land in failed_images
- Verify the board exists before bulk removal
- Check server logs for SQLite 'database is locked' under queue load
When it happens
Trigger: POST /board_images/batch/delete with {image_names, board_id} when the board_images service throws — DB failure, concurrent board deletion, or internal service error while dissociating images.
Common situations: Bulk cleanup scripts hitting a DB that was concurrently pruned, SQLite 'database is locked' under heavy queue load, or stale board_id from a deleted board.
Related errors
- Failed to add images to board
- Failed to remove image from board
- Failed to create board
- Error retrieving recall parameters
- Failed to update board
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/989aa4350144be95.
Report an issue: GitHub.