Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/vrt.py (Python)

Code before:
        'info_dict': {
            'id': '5d47f102-dbdb-4fa0-832b-26c1870311f2',
            'title': 'Europese Unie wil "onmiddellijke humanitaire pauze" en "duurzaam staakt-het-vuren" in Gaza',
            'description': 'md5:1aad1fae7d39edeffde5d3e67d276b64',
            'thumbnail': r're:https?://cds\.vrt\.radio/[^/#\?&]+',
            'display_id': 'europese-unie-wil-onmiddellijke-humanitaire-pauze-en-duurzaam-staakt-het-vuren-in-gaza'
        },
        'playlist_mincount': 1
    }]

    def _extract_video_entries(self, next_js_data, display_id):
        entries = []
        video_data = variadic(traverse_obj(
            next_js_data, {lambda x: x if x.get('mediaReference') else traverse_obj(x, ('paragraphs', ...))}))
        for data in video_data:
            media_reference = data.get('mediaReference')
            if media_reference is None:
                continue
            formats, subtitles = self._extract_formats_and_subtitles(self._call_api(media_reference), display_id)

            entries.append({
                'id': media_reference,
                'formats': formats,
                'subtitles': subtitles,
                **traverse_obj(data, {
                    'title': 'title',
                    'description': ('body', {clean_html})
                })
            })
        return entries

    def _real_extract(self, url):
        display_id = self._match_valid_url(url).group('display_id')
        webpage = self._download_webpage(url, display_id)
        next_js_data = self._search_nextjs_data(webpage, display_id)['props']['pageProps']['item']

        entries = self._extract_video_entries(next_js_data, display_id)
        playlist_info = merge_dicts(
            traverse_obj(next_js_data, ({
                'id': 'id',
                'title': 'title',
                'description': (('description', 'content'), {clean_html}),
            }), get_all=False),
            {
                'title': self._html_search_meta(['name', 'og:title', 'twitter:title'], webpage),
                'description': self._html_search_meta(['description', 'og:description', 'twitter:description'], webpage),
                'thumbnail': self._html_search_meta(['og:image', 'twitter:image'], webpage)
            }
        )
        return self.playlist_result(
            entries, playlist_id=playlist_info['id'], display_id=display_id, **traverse_obj(playlist_info, {

Review comment (suggestion):
Just to be sure, let's also validate the type
```suggestion
                    'title': ('title', {str}),
```

Code after:
            'id': '5d47f102-dbdb-4fa0-832b-26c1870311f2',
            'title': 'Europese Unie wil "onmiddellijke humanitaire pauze" en "duurzaam staakt-het-vuren" in Gaza',
            'description': 'md5:1aad1fae7d39edeffde5d3e67d276b64',
            'thumbnail': r're:https?://cds\.vrt\.radio/[^/#\?&]+',
            'display_id': 'europese-unie-wil-onmiddellijke-humanitaire-pauze-en-duurzaam-staakt-het-vuren-in-gaza'
        },
        'playlist_mincount': 1
    }]

    def _extract_video_entries(self, next_js_data, display_id):
        video_data = traverse_obj(
            next_js_data, ((None, ('paragraphs', ...)), {lambda x: x if x['mediaReference'] else None}))
        for data in video_data:
            media_reference = data['mediaReference']
            formats, subtitles = self._extract_formats_and_subtitles(
                self._call_api(media_reference), display_id)

            yield {
                'id': media_reference,
                'formats': formats,
                'subtitles': subtitles,
                **traverse_obj(data, {
                    'title': ('title', {str}),
                    'description': ('body', {clean_html})
                }),
            }

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)
        next_js_data = self._search_nextjs_data(webpage, display_id)['props']['pageProps']['item']

        return self.playlist_result(
            self._extract_video_entries(next_js_data, display_id), **merge_dicts(traverse_obj(
                next_js_data, ({
                    'id': ('id', {str}),
                    'title': ('title', {str}),
                    'description': (('description', 'content'), {clean_html}),
                }), get_all=False), {
                    'display_id': display_id,
                    'title': self._html_search_meta(['name', 'og:title', 'twitter:title'], webpage),
                    'description': self._html_search_meta(['description', 'og:description', 'twitter:description'], webpage),
                    'thumbnail': self._html_search_meta(['og:image', 'twitter:image'], webpage),
            }))