diff --git a/yt_dlp/update.py b/yt_dlp/update.py index 21f67ec783..5acc5175c9 100644 --- a/yt_dlp/update.py +++ b/yt_dlp/update.py @@ -227,6 +227,10 @@ def _make_label(origin, tag, version=None): return f'{origin}@{tag}' +class _GitHubError(Exception): + pass + + @dataclass class UpdateInfo: """ @@ -319,7 +323,14 @@ class Updater: path = 'latest/download' if tag == 'latest' else f'download/{tag}' url = f'https://github.com/{self.requested_repo}/releases/{path}/{name}' self.ydl.write_debug(f'Downloading {name} from {url}') - return self.ydl.urlopen(url).read() + response = self.ydl.urlopen(url) + # GitHub may send an error webpage response with HTTP status 200 + # See https://github.com/yt-dlp/yt-dlp/issues/17550 + prefix = response.read(512) + if b'' in prefix: + raise _GitHubError('got error webpage instead of release asset') + + return prefix + response.read() def _call_api(self, tag): tag = f'tags/{tag}' if tag != 'latest' else tag @@ -358,7 +369,7 @@ class Updater: for tag in source_tags: try: return self._download_asset('_update_spec', tag=tag).decode() - except network_exceptions as error: + except (_GitHubError, *network_exceptions) as error: if isinstance(error, HTTPError) and error.status == 404: continue self._report_network_error(f'fetch update spec: {error}') @@ -462,7 +473,7 @@ class Updater: if not is_non_updateable(): try: hashes = self._download_asset('SHA2-256SUMS', result_tag) - except network_exceptions as error: + except (_GitHubError, *network_exceptions) as error: if not isinstance(error, HTTPError) or error.status != 404: self._report_network_error(f'fetch checksums: {error}') return None @@ -525,7 +536,7 @@ class Updater: try: newcontent = self._download_asset(update_info.binary_name, update_info.tag) - except network_exceptions as e: + except (_GitHubError, *network_exceptions) as e: if isinstance(e, HTTPError) and e.status == 404: return self._report_error( f'The requested tag {self.requested_repo}@{update_info.tag} does not exist', True)