{"record":{"id":"d3a03e4f56f42467","repo":"immich-app/immich","slug":"asset-not-found-or-asset-is-not-a-video","errorCode":null,"errorMessage":"Asset not found or asset is not a video","messagePattern":"Asset not found or asset is not a video","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/src/services/asset-media.service.ts","lineNumber":306,"sourceCode":"    const fileNameBase =\n      auth.sharedLink && !auth.sharedLink.showExif ? id : getFileNameWithoutExtension(originalFileName);\n    const fileName = `${fileNameBase}_${size}${getFilenameExtension(path)}`;\n\n    return new ImmichFileResponse({\n      fileName,\n      path,\n      contentType: mimeTypes.lookup(path),\n      cacheControl: CacheControl.PrivateWithCache,\n    });\n  }\n\n  async playbackVideo(auth: AuthDto, id: string): Promise<ImmichFileResponse> {\n    await this.requireAccess({ auth, permission: Permission.AssetView, ids: [id] });\n\n    const asset = await this.assetRepository.getForVideo(id);\n\n    if (!asset) {\n      throw new NotFoundException('Asset not found or asset is not a video');\n    }\n\n    const filepath = asset.encodedVideoPath || asset.originalPath;\n\n    return new ImmichFileResponse({\n      path: filepath,\n      contentType: mimeTypes.lookup(filepath),\n      cacheControl: CacheControl.PrivateWithCache,\n    });\n  }\n\n  async bulkUploadCheck(auth: AuthDto, dto: AssetBulkUploadCheckDto): Promise<AssetBulkUploadCheckResponseDto> {\n    const checksums: Buffer[] = dto.assets.map((asset) => fromChecksum(asset.checksum));\n    const results = await this.assetRepository.getByChecksums(auth.user.id, checksums);\n    const checksumMap: Record<string, { id: string; isTrashed: boolean }> = {};\n\n    for (const { id, deletedAt, checksum } of results) {\n      checksumMap[checksum.toString('hex')] = { id, isTrashed: !!deletedAt };","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/asset-media.service.ts#L288-L324","documentation":"playbackVideo streams the video rendition (encoded video, falling back to the original path). getForVideo returns null when the id does not exist or the record is not a video asset, so the service throws NotFoundException('Asset not found or asset is not a video').","triggerScenarios":"GET /api/assets/:id/video/playback with an id belonging to a photo/JPEG asset, a deleted asset, or a malformed/nonexistent id.","commonSituations":"Clients hardcoding a video endpoint for mixed asset lists; stale ids after an asset was deleted or the library was re-scanned; shared-link access to an asset excluded from the link.","solutions":["Check asset.type === 'VIDEO' client-side before calling the playback endpoint.","Verify the asset id is valid and the asset still exists (GET /api/assets/:id).","If the asset should be a video, confirm the upload finished and the type was detected correctly.","Fall back to the thumbnail/preview endpoint for non-video assets."],"exampleFix":"// before\nawait fetch(`${base}/api/assets/${id}/video/playback`);\n// after\nconst asset = await (await fetch(`${base}/api/assets/${id}`)).json();\nif (asset.type === 'VIDEO') await fetch(`${base}/api/assets/${id}/video/playback`);","handlingStrategy":"validation","validationCode":"const asset = await getAssetInfo(id);\nif (asset.type !== 'VIDEO') throw new Error(`Asset ${id} is not a video`);","typeGuard":"const isVideo = (a: { type: string }): a is { type: 'VIDEO' } => a.type === 'VIDEO';","tryCatchPattern":"try { return await getVideoPlayback(id); } catch (e) { if (e.status === 404) return null; throw e; }","preventionTips":["Check asset.type before choosing the playback endpoint","Refresh cached asset lists to avoid stale ids","Handle 404 by falling back to the asset's thumbnail in UIs"],"tags":["not-found","video","type-mismatch","asset"],"backgroundTag":"resource-not-found","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}