{"record":{"id":"ac7a2af01fe58b17","repo":"invoke-ai/InvokeAI","slug":"video-file-not-found","errorCode":null,"errorMessage":"Video file not found","messagePattern":"Video file not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"invokeai/app/api/routers/videos.py","lineNumber":616,"sourceCode":"\n    Browser media requests authenticate with the path-scoped HttpOnly cookie set at login.\n    \"\"\"\n    _assert_video_read_access(video_name, current_user)\n    try:\n        path_str = ApiDependencies.invoker.services.videos.get_path(video_name, thumbnail=False)\n    except Exception:\n        raise HTTPException(status_code=404)\n\n    # Open once and serve every branch from the fd. Deletion stages files away via an\n    # atomic rename, so any later path-based stat/open — including FileResponse's lazy\n    # open after the route returns — races with a concurrent delete and surfaces as an\n    # uncontrolled 500. An open fd is immune: the data stays readable until the handle\n    # closes, even after the path is gone.\n    video_file: Optional[BinaryIO] = None\n    try:\n        video_file = open(path_str, \"rb\")\n    except OSError:\n        raise HTTPException(status_code=404)\n\n    try:\n        file_size = os.fstat(video_file.fileno()).st_size\n        range_header = request.headers.get(\"range\") or request.headers.get(\"Range\")\n\n        common_headers = {\n            \"Accept-Ranges\": \"bytes\",\n            \"Cache-Control\": _get_video_cache_control(),\n            \"Content-Disposition\": f'inline; filename=\"{video_name}\"',\n        }\n\n        # HEAD: respond with metadata only.\n        if request.method == \"HEAD\":\n            return Response(\n                status_code=200,\n                media_type=\"video/mp4\",\n                headers={**common_headers, \"Content-Length\": str(file_size)},\n            )","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/api/routers/videos.py#L598-L634","documentation":"Raised by get_video_full as HTTP 404 when open(path_str, 'rb') raises OSError after the path was resolved. The record exists but the file on disk is gone or unreadable — a DB/filesystem mismatch. The code opens the fd once (rather than letting FileResponse lazily open by path) precisely to avoid racing with concurrent deletes; this 404 is the controlled outcome when the open still fails.","triggerScenarios":"open() fails with FileNotFoundError (file deleted/moved), PermissionError, or EACCES/EIO on the resolved video path; outputs dir partially deleted or on a failed mount.","commonSituations":"Manual cleanup of the outputs folder while records remain; moving/reinstalling InvokeAI without migrating files; read-only mounts; antivirus or backup tools locking/removing files mid-read.","solutions":["Check that the file at the resolved path exists and is readable (ls -l, stat).","Delete the orphaned record via the API so DB and disk stay consistent, then re-upload/re-generate.","Fix permissions or remount the outputs directory if the OSError is permission/device related.","Inspect server logs for the exact OSError errno to distinguish missing-file from I/O errors."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(mediaUrl, { headers });\n  if (!res.ok && res.status === 404) {\n    showPlaceholder(); // record exists but file missing — DB/disk mismatch\n  }\n} catch (e) {\n  showPlaceholder();\n}","preventionTips":["Never delete files directly from the outputs directory — use the API so records stay consistent.","Monitor disk/mount health; read-only mounts surface as this 404.","On 404 for an existing DTO, reconcile by deleting the orphaned record server-side."],"tags":["http-404","filesystem","video","oserror"],"backgroundTag":"file-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}