immich-app/immich · error · BadRequestException
Library ${id} not found
Error message
Library ${id} not found What it means
LibraryService.getStatistics calls libraryRepository.getStatistics(id); if the repository returns no statistics row (typically because no library with that id exists), it throws 400 BadRequestException 'Library {id} not found'. Note this uses the statistics lookup as an existence proxy, so the error fires for a missing library rather than via findOrFail.
Source
Thrown at server/src/services/library.service.ts:202
await this.unwatch(id);
}
}
async watchAll() {
if (!this.lock) {
return false;
}
const libraries = await this.libraryRepository.getAll(false);
for (const library of libraries) {
await this.watch(library.id);
}
}
async getStatistics(id: string): Promise<LibraryStatsResponseDto> {
const statistics = await this.libraryRepository.getStatistics(id);
if (!statistics) {
throw new BadRequestException(`Library ${id} not found`);
}
return statistics;
}
async get(id: string): Promise<LibraryResponseDto> {
const library = await this.findOrFail(id);
return mapLibrary(library);
}
async getAll(): Promise<LibraryResponseDto[]> {
const libraries = await this.libraryRepository.getAll(false);
return libraries.map((library) => mapLibrary(library));
}
@OnJob({ name: JobName.LibraryDeleteCheck, queue: QueueName.Library })
async handleQueueCleanup(): Promise<JobStatus> {
this.logger.log('Checking for any libraries pending deletion...');
const pendingDeletions = await this.libraryRepository.getAllDeleted();View on GitHub (pinned to 199723261c)
Solutions
- List libraries via GET /libraries and use a valid id from the response.
- If the library was deleted, stop referencing it.
- Confirm the id format is a valid UUID and matches an existing library.
Example fix
// before
api.library.getStatistics('not-a-real-id');
// after
const libs = await api.library.getAll();
await api.library.getStatistics(libs[0].id); Defensive patterns
Strategy: validation
Validate before calling
const libs = await api.libraryApi.getAll();
const exists = libs.some((l) => l.id === id);
if (!exists) throw new Error(`Library ${id} does not exist`);
await api.libraryApi.getStatistics(id); Type guard
const libraryExists = (id: string, libraries: { id: string }[]) =>
libraries.some((l) => l.id === id); Try / catch
try {
return await api.libraryApi.getStatistics(id);
} catch (e) {
if (e.status === 400 && /not found/.test(e.message)) {
// refresh library list, drop stale id
} else throw e;
} Prevention
- Cache the library list and validate ids against it before sub-resource calls.
- Handle library deletions in the UI by invalidating cached ids.
- Use GET /libraries as the source of truth for valid ids.
When it happens
Trigger: GET /libraries/{id}/statistics where id does not correspond to any library row. Caused by a deleted library, a wrong UUID copied from the UI, or a stale client reference.
Common situations: Library was deleted but the admin UI still had the link open; typo in id; script iterating over cached ids after a re-import.
Related errors
- Invalid import path: ${path.message}
- Notification not found
- assetIds, albumId, or userId is required
- Invalid job name
- User not found
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/0589e18b6f887bd9.
Report an issue: GitHub.