immich-app/immich · warning · BadRequestException
Asset has no embedding
Error message
Asset ${dto.queryAssetId} has no embedding What it means
resolveEmbedding supports searching by an existing asset: it fetches the asset's stored smart-search embedding and throws when the asset exists but has no embedding. This happens for assets whose smart-search embedding was never generated or was wiped (e.g. ML disabled previously).
Solutions
- Wait for/backfill ML jobs so the asset gets an embedding (re-run machine learning job for the asset)
- Pick a different queryAssetId known to have embeddings, or send a text `query` instead
- Enable smart search/ML service so new assets get embedded
- Check asset status before using it as a similarity seed
Example fix
// before
await api.searchSmart({ queryAssetId: freshUploadId }); // may throw
// after
if (asset.smartSearchStatus === 'ok') {
await api.searchSmart({ queryAssetId: asset.id });
} else {
await api.searchSmart({ query: asset.originalFileName }); Defensive patterns
Strategy: fallback
Validate before calling
if (asset.smartSearch?.status !== 'ok') {
// embedding not ready; use text query instead
return await api.searchSmart({ query: asset.originalFileName });
} Type guard
function hasEmbedding(a: { smartSearch?: { status?: string } }): boolean {
return a.smartSearch?.status === 'ok';
} Try / catch
try {
return await searchService.searchSmart(auth, { queryAssetId });
} catch (e) {
if (e instanceof BadRequestException && /has no embedding/.test(e.message)) {
return await searchService.searchSmart(auth, { query: fallbackText });
}
throw e;
} Prevention
- Ensure ML jobs complete before using assets as similarity seeds
- Re-run embedding jobs after enabling smart search on old libraries
- Prefer text queries when asset embedding status is unknown
When it happens
Trigger: Smart search with `queryAssetId` set to an asset that (a) has no embedding row yet because ML hasn't processed it, (b) had embeddings cleared, or (c) was uploaded while smart search was disabled.
Common situations: Building 'find similar' UIs on freshly uploaded assets before ML jobs run; installations that recently enabled smart search so old assets lack embeddings; assets queued but ML service down.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Smart search is not enabled
- Attempted to clear cache, but rmtree is not safe on this…
- Either image or text must be provided
- Either `query` or `queryAssetId` must be set
- Failed to load model
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/2cf9bb520f9846a0.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/search.service.ts:348
if (dto.query) {
const key = machineLearning.clip.modelName + dto.query + dto.language;
let 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);
}
return embedding;
}
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;
if (!assetEmbedding) {
throw new BadRequestException(`Asset ${dto.queryAssetId} has no embedding`);
}
return assetEmbedding;
}
throw new BadRequestException('Either `query` or `queryAssetId` must be set');
}
private async getUserIdsToSearch(auth: AuthDto, visibility?: AssetVisibility): Promise<string[]> {
// Locked assets are personal. Never include partner IDs, regardless of A's elevated session.
if (visibility === AssetVisibility.Locked) {
return [auth.user.id];
}
const partnerIds = await getMyPartnerIds({
userId: auth.user.id,
repository: this.partnerRepository,
timelineEnabled: true,
});
return [auth.user.id, ...partnerIds];View on GitHub (pinned to e55ac299a4)