ytdl-org/youtube-dl · error · ExtractorError
Unable to parse __NEXT_DATA__
Error message
Unable to parse __NEXT_DATA__
What it means
Raised by the UR Play (urplay.se) extractor when it finds a __NEXT_DATA__ script tag on the page but cannot turn it into usable program data — either json parsing failed (fatal=False swallows the parse error) or the expected props.pageProps.program dict is absent after traversal. It means the Next.js page structure changed or the JSON was truncated, so the primary extraction path is dead.
Source
Thrown at youtube_dl/extractor/urplay.py:65
'episode': 'Sovkudde',
},
}, {
'url': 'http://urskola.se/Produkter/155794-Smasagor-meankieli-Grodan-i-vida-varlden',
'only_matching': True,
}]
def _real_extract(self, url):
video_id = self._match_id(url)
url = url.replace('skola.se/Produkter', 'play.se/program')
webpage = self._download_webpage(url, video_id)
urplayer_data = self._search_regex(
r'(?s)\bid\s*=\s*"__NEXT_DATA__"[^>]*>\s*({.+?})\s*</script',
webpage, 'urplayer next data', fatal=False) or {}
if urplayer_data:
urplayer_data = self._parse_json(urplayer_data, video_id, fatal=False)
urplayer_data = try_get(urplayer_data, lambda x: x['props']['pageProps']['program'], dict)
if not urplayer_data:
raise ExtractorError('Unable to parse __NEXT_DATA__')
else:
accessible_episodes = self._parse_json(self._html_search_regex(
r'data-react-class="routes/Product/components/ProgramContainer/ProgramContainer"[^>]+data-react-props="({.+?})"',
webpage, 'urplayer data'), video_id)['accessibleEpisodes']
urplayer_data = next(e for e in accessible_episodes if e.get('id') == int_or_none(video_id))
episode = urplayer_data['title']
raw_streaming_info = urplayer_data['streamingInfo']['raw']
host = self._download_json(
'http://streaming-loadbalancer.ur.se/loadbalancer.json',
video_id)['redirect']
formats = []
for k, v in raw_streaming_info.items():
if not (k in ('sd', 'hd') and isinstance(v, dict)):
continue
file_http = v.get('location')
if file_http:
formats.extend(self._extract_wowza_formats(View on GitHub (pinned to 956b8c5855)
Solutions
- Open the URL in a browser and inspect the __NEXT_DATA__ script to see the new JSON shape (e.g. program moved or renamed under pageProps).
- Update the try_get path in the extractor to the current location of the program object.
- If the script tag itself is gone, extend the fallback branch (the data-react-class ProgramContainer path) or add a new regex for the current markup.
- On an outdated youtube-dl install, upgrade first — UR Play layout changes are usually fixed upstream quickly.
Example fix
// before urplayer_data = try_get(urplayer_data, lambda x: x['props']['pageProps']['program'], dict) // after (adapt to actual new location, e.g. pageReward renamed) urplayer_data = try_get(urplayer_data, lambda x: x['props']['pageProps']['program'], dict) or try_get(urplayer_data, lambda x: x['props']['pageProps']['data']['program'], dict)
Defensive patterns
Strategy: validation
Validate before calling
import json, re
html = fetch(url)
m = re.search(r'(?s)\bid\s*=\s*"__NEXT_DATA__"[^>]*>\s*({.+?})\s*</script', html)
if not m:
raise SystemExit('site markup changed: no __NEXT_DATA__ script')
data = json.loads(m.group(1))
if not (data.get('props', {}).get('pageProps', {}).get('program')):
raise SystemExit('pageProps.program missing — extractor needs updating') Try / catch
try:
info = ydl.extract_info(url)
except ExtractorError as e:
if '__NEXT_DATA__' in str(e):
report_extractor_bug('urplay', url, e) # layout change: file issue, fall back to manual inspection
else:
raise Prevention
- Pin a known-good youtube-dl version for production scrapes and test site-specific extractors after site updates.
- Wrap single-site scrapers so a layout-change error quarantines only that site's URLs.
- Cache successful extraction results to avoid re-hitting fragile pages.
When it happens
Trigger: Extracting any urplay.se/program (or skola.se/Produkter) URL where the regex matches the __NEXT_DATA__ script but _parse_json or try_get(...['props']['pageProps']['program']) yields None.
Common situations: UR Play ships a site redesign that renames pageProps.program, moves data to another key, or server-renders differently; A/B variant pages; the regex captures a partial JSON blob on very large pages.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/d8d050e85ef3be3c.
Report an issue: GitHub.