Fix YouTube 403s by upgrading yt-dlp to 2026.8.19
Every YouTube download — /force and the normal clip path alike — was failing at the data-transfer stage with "HTTP Error 403: Forbidden". Extraction succeeded and a format was selected; only the media fetch died, which is why it read as a per-video problem rather than a broken extractor. The cause was YouTube retiring the cookieless `android_vr` client that yt-dlp 2026.6.9 pinned. Its media URLs now 403 for every video, so the failure was global rather than specific to the video that surfaced it. 2026.8.19 re-points at `visionos` and downloads work again. Refresh the cookie-withholding note, which named android_vr as the client whose URLs work, and record the 403-on-data-transfer signature as the tell for a retired client so the next occurrence goes straight to a yt-dlp upgrade instead of the cookie or format logic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QH4jMHfUTDhm41BrRtkPc3
This commit is contained in:
@@ -62,10 +62,18 @@ _NODE22 = "/opt/node22/bin/node"
|
||||
JS_RUNTIME = f"node:{_NODE22}" if os.path.exists(_NODE22) else "node"
|
||||
|
||||
# YouTube is the one host where we must NOT send cookies: with account cookies
|
||||
# present, yt-dlp skips the cookieless `android_vr`/`android` clients (whose media
|
||||
# URLs work) and falls back to the `tv` client, whose URLs now 403 on the data
|
||||
# download. A cookieless YouTube request just works. Cookies are still needed for
|
||||
# Instagram/TikTok/X, so we withhold them per-URL rather than dropping the file.
|
||||
# present, yt-dlp skips the cookieless client it would otherwise pick (currently
|
||||
# `visionos`, which offers the full ladder of split renditions) and falls back to
|
||||
# a `tv` client that only ever yields muxed 360p — and whose URLs have repeatedly
|
||||
# 403'd on the data download. A cookieless YouTube request just works. Cookies are
|
||||
# still needed for Instagram/TikTok/X, so we withhold them per-URL rather than
|
||||
# dropping the file.
|
||||
#
|
||||
# Which cookieless client yt-dlp picks is not stable — YouTube retires them and
|
||||
# yt-dlp re-points at a working one. When every YouTube download starts failing at
|
||||
# the data stage with "HTTP Error 403: Forbidden" (extraction succeeds, the
|
||||
# transfer does not), that is the signal that the pinned client has been retired:
|
||||
# upgrade yt-dlp rather than touching the cookie or format logic here.
|
||||
_YOUTUBE_HOST_RE = re.compile(r"(?:^|\.)(?:youtube\.com|youtu\.be|youtube-nocookie\.com)$", re.I)
|
||||
|
||||
def _is_youtube(url: str) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user