{"record":{"id":"29240cee19bd9322","repo":"immich-app/immich","slug":"no-file-found-for-the-video","errorCode":null,"errorMessage":"No file found for the video","messagePattern":"No file found for the video","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart","lineNumber":121,"sourceCode":"  }\n\n  Future<VideoSource?> _createSource() async {\n    if (!mounted) {\n      return null;\n    }\n\n    final videoAsset = await ref.read(assetServiceProvider).getAsset(widget.asset) ?? widget.asset;\n    if (!mounted) {\n      return null;\n    }\n\n    try {\n      final localFilePath = widget.localFilePath;\n      if (localFilePath != null) {\n        final file = File(localFilePath);\n        // ignore: avoid_slow_async_io\n        if (!await file.exists()) {\n          throw Exception('No file found for the video');\n        }\n\n        return await VideoSource.init(\n          path: CurrentPlatform.isAndroid ? file.uri.toString() : file.path,\n          type: VideoSourceType.file,\n        );\n      }\n\n      // Attempt to retrieve LocalAsset, falling back to remote if it cannot be found\n      final localAsset = await _localPlaybackAsset(videoAsset);\n\n      if (localAsset != null) {\n        final file = localAsset.isMotionPhoto\n            ? await StorageRepository().getMotionFileForAsset(localAsset)\n            : await StorageRepository().getFileForAsset(localAsset.id);\n\n        if (!mounted) {\n          return null;","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart#L103-L139","documentation":"Thrown during video player source initialization in VideoViewerWidget when a localFilePath was supplied but the file does not exist on disk. VideoSource.init with VideoSourceType.file would fail otherwise, so the widget validates existence first with File.exists(). It means the player was handed a path whose backing file was removed or never downloaded.","triggerScenarios":"widget.localFilePath is non-null but the file at that path cannot be found — e.g. the local cache was cleared, the asset was deleted, or the path was recorded before the download completed.","commonSituations":"OS/storage cleaner evicted cached video files; app data cleared between sessions; a stale DB record pointing to a removed temp file; path stored before a cancelled download.","solutions":["Check File.existsSync(localFilePath) before initializing the player and fall back to streaming the remote asset instead.","Trigger a re-download of the asset if the local copy is missing.","Purge stale localFilePath entries from local storage/DB when files are evicted.","Handle the exception in the player UI by showing a 'video unavailable' state and retry logic."],"exampleFix":"// before\nif (!await file.exists()) {\n  throw Exception('No file found for the video');\n}\n// after\nif (!await file.exists()) {\n  // fall back to remote streaming source instead of throwing\n  return await VideoSource.init(url: widget.asset.remoteUrl, type: VideoSourceType.network);\n}","handlingStrategy":"fallback","validationCode":"final file = File(localFilePath);\nif (!await file.exists()) {\n  // trigger re-download or use remote streaming source\n  return;\n}","typeGuard":"Future<bool> hasLocalFile(String? path) async =>\n    path != null && await File(path).exists();","tryCatchPattern":"try {\n  final source = await initVideoSource();\n  // attach player\n} catch (e) {\n  setState(() => playbackError = 'Video file missing; streaming remotely...');\n  await playFromRemote();\n}","preventionTips":["Verify File.exists() before handing paths to the video player","Fall back to remote streaming when the local cache misses","Purge DB/localFilePath entries when cache files are evicted","Re-download assets whose local files disappeared"],"tags":["flutter","video","filesystem","local-storage"],"backgroundTag":"file-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"}