ytdl-org/youtube-dl · error · ExtractorError
%s said: %s
Error message
%s said: %s
What it means
Raised by the FilmOn VOD extractor when the API request to https://www.filmon.com/api/vod/movie?id=<id> fails with an HTTP error and the error body contains a 'reason' field. The extractor re-raises the server's own reason prefixed with the extractor name. It is marked expected=True, so it represents a server-side rejection (bad ID, removed movie, region block) rather than a parsing bug.
Source
Thrown at youtube_dl/extractor/filmon.py:48
'info_dict': {
'id': '2825',
'title': 'Popeye Series 1',
'description': 'The original series of Popeye.',
},
'playlist_mincount': 8,
}]
def _real_extract(self, url):
video_id = self._match_id(url)
try:
response = self._download_json(
'https://www.filmon.com/api/vod/movie?id=%s' % video_id,
video_id)['response']
except ExtractorError as e:
if isinstance(e.cause, compat_HTTPError):
errmsg = self._parse_json(e.cause.read().decode(), video_id)['reason']
raise ExtractorError('%s said: %s' % (self.IE_NAME, errmsg), expected=True)
raise
title = response['title']
description = strip_or_none(response.get('description'))
if response.get('type_id') == 1:
entries = [self.url_result('filmon:' + episode_id) for episode_id in response.get('episodes', [])]
return self.playlist_result(entries, video_id, title, description)
QUALITY = qualities(('low', 'high'))
formats = []
for format_id, stream in response.get('streams', {}).items():
stream_url = stream.get('url')
if not stream_url:
continue
formats.append({
'format_id': format_id,
'url': stream_url,View on GitHub (pinned to 956b8c5855)
Solutions
- Open https://www.filmon.com/vod/view/movie-<id> in a browser to confirm the title is still listed and playable in your region
- Correct the movie id if it was mistyped or truncated from the URL
- Use a region-appropriate exit IP (FilmOn VOD rights vary by country)
- Retry later if the reason text indicates a temporary API problem
Example fix
# before youtube_dl 'https://www.filmon.com/vod/view/movie-999999' # ERROR: FilmOn said: <reason> # after youtube_dl 'https://www.filmon.com/vod/view/movie-12345' # valid, in-catalog id
Defensive patterns
Strategy: try-catch
Try / catch
try:
info = ydl.extract_info('filmon:movie-%s' % movie_id)
except ExtractorError as e:
if str(e).startswith('FilmOn said:'):
drop_movie_from_catalog(movie_id) # server rejected; do not retry blindly Prevention
- Validate movie ids against the FilmOn catalog page before extraction
- Cache 'FilmOn said:' failures so crawlers do not re-hit dead ids
When it happens
Trigger: _download_json raises ExtractorError whose cause is a compat_HTTPError; the code reads the response body and parses 'reason' from the JSON. Produced by requesting a nonexistent or delisted movie id, a VOD item not licensed for your region, or transient FilmOn API failures.
Common situations: Following outdated filmon: movie links; scraping channel guides whose movie entries expired; hitting the API from a region where FilmOn has no VOD rights.
Related errors
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/902baedd12b840ec.
Report an issue: GitHub.