immich-app/immich · warning
Skipping thumbnail generation for asset
Error message
Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video What it means
Thumbnail generation only supports AssetType.Video and AssetType.Image. If the asset's type enum holds any other value (or an unexpected type string), the handler logs this warning and returns JobStatus.Skipped rather than throwing on an unhandled media kind.
Solutions
- Inspect the row: SELECT type FROM asset WHERE id = '<id>'; and correct it to IMAGE or VIDEO if wrong
- Re-upload the asset if type detection corrupted it
- Re-run metadata extraction to re-derive the asset type
- Update the server to a version that handles the asset type in question
Example fix
// before
} else { this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video`); return JobStatus.Skipped; }
// after
} else { this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video`); await this.assetRepository.update({ id, type: await detectType(asset.originalPath) }); return JobStatus.Failed; } Defensive patterns
Strategy: type-guard
Validate before calling
if (asset.type !== AssetType.Image && asset.type !== AssetType.Video) {
// re-run metadata extraction or flag the asset for review
} Type guard
function isThumbnailable(t: AssetType): boolean { return t === AssetType.Image || t === AssetType.Video; } Try / catch
if (!isThumbnailable(asset.type)) { this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type}`); return JobStatus.Skipped; } Prevention
- Never hand-edit asset.type values in the database
- Re-run metadata extraction if type detection looks wrong
- Keep server and DB schema versions in sync
- Validate uploaded files produce a known asset type
When it happens
Trigger: handleGenerateThumbnails receives an asset whose asset.type is neither Video nor Image — typically a malformed type value in the database or a newly introduced type not yet handled by the media service.
Common situations: Manually edited or migrated database rows with unexpected type values; uploads whose type detection misclassified the file; running an older server against a database written by a newer version that added a type.
Related errors
- Asset has transparency but the configured format is which…
- Invalid ack type
- Invalid job name
- Invalid targetSize: ' + targetSize
- Thumbnail generation failed for asset
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/e130e9a8d3e0accd.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/media.service.ts:216
if (!asset) {
this.logger.warn(`Thumbnail generation failed for asset ${id}: not found in database or missing metadata`);
return JobStatus.Failed;
}
if (asset.visibility === AssetVisibility.Hidden) {
this.logger.verbose(`Thumbnail generation skipped for asset ${id}: not visible`);
return JobStatus.Skipped;
}
let generated: Awaited<ReturnType<MediaService['generateImageThumbnails']>>;
if (asset.type === AssetType.Video || asset.originalFileName.toLowerCase().endsWith('.gif')) {
this.logger.verbose(`Thumbnail generation for video ${id} ${asset.originalPath}`);
generated = await this.generateVideoThumbnails(asset, config);
} else if (asset.type === AssetType.Image) {
this.logger.verbose(`Thumbnail generation for image ${id} ${asset.originalPath}`);
generated = await this.generateImageThumbnails(asset, config);
} else {
this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video`);
return JobStatus.Skipped;
}
const editedGenerated = await this.generateEditedThumbnails(asset, config);
if (editedGenerated) {
generated.files.push(...editedGenerated.files);
}
await this.syncFiles(asset.files, generated.files);
const thumbhash = editedGenerated?.thumbhash || generated.thumbhash;
if (!asset.thumbhash || Buffer.compare(asset.thumbhash, thumbhash) !== 0) {
await this.assetRepository.update({ id: asset.id, thumbhash });
}
return JobStatus.Success;
}
View on GitHub (pinned to e55ac299a4)