immich-app/immich · warning · BadRequestException

Smart search is not enabled

Error message

Smart search is not enabled

What it means

Thrown by SearchService.searchSmart when isSmartSearchEnabled(machineLearning) is false, i.e. machineLearning.enabled is false OR machineLearning.clip.enabled is false. CLIP text/image embeddings are required for smart search, so the request cannot be served. BadRequestException -> HTTP 400.

Source

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

    }

    const userIds = await this.getUserIdsToSearch(auth, dto.visibility);
    const items = await this.searchRepository.searchLargeAssets(dto.size || 250, {
      ...dto,
      visibility: dto.visibility ?? (auth.session?.hasElevatedPermission ? undefined : 'not-locked'),
      userIds,
    });
    return items.map((item) => mapAsset(item, { auth }));
  }

  async searchSmart(auth: AuthDto, dto: SmartSearchDto): Promise<SearchResponseDto> {
    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);
    let embedding;
    if (dto.query) {
      const key = machineLearning.clip.modelName + dto.query + dto.language;
      embedding = this.embeddingCache.get(key);
      if (!embedding) {
        embedding = await this.machineLearningRepository.encodeText(dto.query, {
          modelName: machineLearning.clip.modelName,
          language: dto.language,
        });
        this.embeddingCache.set(key, embedding);
      }
    } else if (dto.queryAssetId) {
      await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [dto.queryAssetId] });
      const getEmbeddingResponse = await this.searchRepository.getEmbedding(dto.queryAssetId);
      const assetEmbedding = getEmbeddingResponse?.embedding;

View on GitHub (pinned to 199723261c)

Solutions

  1. Enable Machine Learning in Administration > Machine Learning Settings.
  2. Ensure the CLIP sub-setting is enabled and a model is selected.
  3. Confirm the immich-machine-learning container is running and reachable, then re-enable.
  4. Call GET /server/features to check `smartSearch: true` before exposing the UI.

Example fix

// before
if (!isSmartSearchEnabled(machineLearning)) {
  throw new BadRequestException('Smart search is not enabled');
}

// client-side guard
const features = await api.get('/server/features');
if (!features.smartSearch) {
  showToast('Smart search is disabled. Enable Machine Learning in Administration.');
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

// Check server features before offering smart search.
const features = await serverService.getFeatures();
if (!features.smartSearch) {
  // hide the smart-search UI; do not call /search/smart
  return;
}
await searchService.searchSmart(auth, dto);

Type guard

const isSmartSearchAvailable = (f: ServerFeaturesDto): boolean => !!f.smartSearch;

Try / catch

try {
  await searchService.searchSmart(auth, dto);
} catch (e) {
  if (e instanceof BadRequestException && /Smart search is not enabled/i.test(e.message)) {
    // prompt admin to enable Machine Learning and abort
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /search/smart (or GET /search/smart) when Machine Learning is disabled in Administration > Settings, or when the CLIP variant is disabled.

Common situations: Fresh install without enabling ML; ML server URL misconfigured so the admin toggled ML off; CLIP disabled to save resources; deployment without the immich-machine-learning container.

Related errors


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