immich-app/immich · warning · BadRequestException

Smart search is not enabled

Error message

Smart search is not enabled

What it means

searchSmart checks the server's machine-learning config (freshly fetched, uncached) and throws when smart search is disabled. Smart search (CLIP-style semantic embedding search) is an optional feature that must be enabled in server settings.

Solutions

  1. Enable smart search in Administration > Settings > Machine Learning Settings (Smart Search)
  2. Deploy/configure the machine-learning service if it is missing
  3. Fall back to metadata search in clients when smart search is disabled
  4. Gate the smart-search UI behind a server capability check

Example fix

// before
const res = await api.searchSmart({ query: 'dog' }); // throws if disabled
// after
if (serverFeatures.smartSearch) {
  const res = await api.searchSmart({ query: 'dog' });
} else {
  const res = await api.searchMetadata({});
Defensive patterns

Strategy: fallback

Validate before calling

const features = await api.getServerFeatures();
if (!features.smartSearch) return metadataSearchFallback();

Type guard

function smartSearchAvailable(cfg: { machineLearning: { smartSearch?: { enabled: boolean } } }): boolean {
  return cfg.machineLearning.smartSearch?.enabled === true;
}

Try / catch

try {
  return await searchService.searchSmart(auth, dto);
} catch (e) {
  if (e instanceof BadRequestException && e.message === 'Smart search is not enabled') {
    return searchService.searchMetadata(auth, toMetadataDto(dto));
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /search/smart (or searchSmart service call) while the server config has machine learning smart search turned off (e.g. ML disabled, or the smart-search endpoint setting off).

Common situations: Deployments without a machine-learning container; admins disabled smart search to save resources; self-hosted minimal installs; upgrading where ML was switched off and clients still call smart search.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/f4b27cea10a1751c. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/search.service.ts:179

      visibility: dto.visibility ?? (auth.session?.hasElevatedPermission ? undefined : 'not-locked'),
      userIds,
      viewingUserId: auth.user.id,
    });
    return items.map((item) => mapAsset(item, { auth }));
  }

  async searchSmart(auth: AuthDto, dto: SmartSearchDto): Promise<SearchResponseDto> {
    if (isNewShapeRequest(dto)) {
      return this.searchSmartV3(auth, dto);
    }

    if (dto.visibility === AssetVisibility.Locked) {
      requireElevatedPermission(auth);
    }

    const { machineLearning } = await this.getConfig({ withCache: false });
    if (!isSmartSearchEnabled(machineLearning)) {
      throw new BadRequestException('Smart search is not enabled');
    }

    const userIds = this.getUserIdsToSearch(auth, dto.visibility);
    const embedding = await this.resolveEmbedding(auth, dto, machineLearning);
    const page = dto.page ?? 1;
    const size = dto.size;
    const { hasNextPage, items } = await this.searchRepository.searchSmart(
      { page, size },
      {
        ...dto,
        userIds: await userIds,
        viewingUserId: auth.user.id,
        embedding,
        visibility: dto.visibility ?? (auth.session?.hasElevatedPermission ? undefined : 'not-locked'),
      },
    );

    return this.mapResponse(items, { auth }, { nextPage: hasNextPage ? (page + 1).toString() : null });

View on GitHub (pinned to e55ac299a4)