{"record":{"id":"2cf9bb520f9846a0","repo":"immich-app/immich","slug":"asset-dto-queryassetid-has-no-embedding","errorCode":null,"errorMessage":"Asset ${dto.queryAssetId} has no embedding","messagePattern":"Asset (.+?) has no embedding","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"server/src/services/search.service.ts","lineNumber":170,"sourceCode":"\n    const userIds = this.getUserIdsToSearch(auth, dto.visibility);\n    let embedding;\n    if (dto.query) {\n      const key = machineLearning.clip.modelName + dto.query + dto.language;\n      embedding = this.embeddingCache.get(key);\n      if (!embedding) {\n        embedding = await this.machineLearningRepository.encodeText(dto.query, {\n          modelName: machineLearning.clip.modelName,\n          language: dto.language,\n        });\n        this.embeddingCache.set(key, embedding);\n      }\n    } else if (dto.queryAssetId) {\n      await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [dto.queryAssetId] });\n      const getEmbeddingResponse = await this.searchRepository.getEmbedding(dto.queryAssetId);\n      const assetEmbedding = getEmbeddingResponse?.embedding;\n      if (!assetEmbedding) {\n        throw new BadRequestException(`Asset ${dto.queryAssetId} has no embedding`);\n      }\n      embedding = assetEmbedding;\n    } else {\n      throw new BadRequestException('Either `query` or `queryAssetId` must be set');\n    }\n    const page = dto.page ?? 1;\n    const size = dto.size || 100;\n    const { hasNextPage, items } = await this.searchRepository.searchSmart(\n      { page, size },\n      {\n        ...dto,\n        userIds: await userIds,\n        embedding,\n        visibility: dto.visibility ?? (auth.session?.hasElevatedPermission ? undefined : 'not-locked'),\n      },\n    );\n\n    return this.mapResponse(items, hasNextPage ? (page + 1).toString() : null, { auth });","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/search.service.ts#L152-L188","documentation":"Thrown by SearchService.searchSmart when dto.queryAssetId is set, the asset is readable, but searchRepository.getEmbedding(dto.queryAssetId) returns no row (or no embedding column). Means the asset has never been embedded by the CLIP job, so it cannot be used as a search-by-image anchor. BadRequestException -> HTTP 400.","triggerScenarios":"POST /search/smart with queryAssetId for an asset whose SmartSearch embedding job has not yet run or failed; brand-new upload; an asset type that CLIP skips (e.g. some RAW files).","commonSituations":"SmartSearch queue is behind; asset was uploaded after the last embedding pass; CLIP job failed for that asset (corrupt decode); ML server was down during ingestion.","solutions":["Wait for or trigger the SmartSearch queue (Administration > Jobs) to embed the asset.","Check the asset has a successful metadata extraction first (CLIP depends on it).","Fall back to a text query (dto.query) instead of queryAssetId until embeddings are built.","Verify the immich-machine-learning service is healthy so future assets get embedded."],"exampleFix":"// before\nif (!assetEmbedding) {\n  throw new BadRequestException(`Asset ${dto.queryAssetId} has no embedding`);\n}\n\n// client-side guard\nconst embedding = await api.get(`/assets/${queryAssetId}/embedding`);\nif (!embedding) {\n  showToast('This asset has no smart embedding yet. Run the Smart Search job.');\n  return;\n}","handlingStrategy":"validation","validationCode":"// Confirm the asset has an embedding before using it as a query anchor.\nconst embedding = await searchRepository.getEmbedding(queryAssetId);\nif (!embedding?.embedding) {\n  // queue SmartSearch for this asset and fall back to text query\n  throw new Error(`Asset ${queryAssetId} has no embedding yet`);\n}","typeGuard":"const hasEmbedding = (e: { embedding?: string } | null | undefined): e is { embedding: string } =>\n  !!e && typeof e.embedding === 'string' && e.embedding.length > 0;","tryCatchPattern":"try {\n  await searchService.searchSmart(auth, dto);\n} catch (e) {\n  if (e instanceof BadRequestException && /no embedding/i.test(e.message)) {\n    // fall back to a text query\n    return searchService.searchSmart(auth, { ...dto, query: fallbackText, queryAssetId: undefined });\n  }\n  throw e;\n}","preventionTips":["Run the SmartSearch queue before exposing search-by-image.","Fall back to text query when the anchor asset lacks an embedding.","Monitor ML job failures so embeddings are not silently missing."],"tags":["search","machine-learning","clip","embedding","asset","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}