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

  1. List libraries via GET /libraries and use a valid id from the response.
  2. If the library was deleted, stop referencing it.
  3. 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

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


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/0589e18b6f887bd9. Report an issue: GitHub.