{"record":{"id":"764862df29a242a1","repo":"ytdl-org/youtube-dl","slug":"this-content-is-only-available-for-subscribers","errorCode":null,"errorMessage":"This content is only available for subscribers","messagePattern":"This content is only available for subscribers","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/raywenderlich.py","lineNumber":86,"sourceCode":"                if ordinal != lesson_id:\n                    continue\n                video_id = content.get('identifier')\n                if video_id:\n                    return compat_str(video_id)\n\n    def _real_extract(self, url):\n        mobj = re.match(self._VALID_URL, url)\n        course_id, lesson_id = mobj.group('course_id', 'id')\n        display_id = '%s/%s' % (course_id, lesson_id)\n\n        webpage = self._download_webpage(url, display_id)\n\n        thumbnail = self._og_search_thumbnail(\n            webpage, default=None) or self._html_search_meta(\n            'twitter:image', webpage, 'thumbnail')\n\n        if '>Subscribe to unlock' in webpage:\n            raise ExtractorError(\n                'This content is only available for subscribers',\n                expected=True)\n\n        info = {\n            'thumbnail': thumbnail,\n        }\n\n        vimeo_id = self._search_regex(\n            r'data-vimeo-id=[\"\\'](\\d+)', webpage, 'vimeo id', default=None)\n\n        if not vimeo_id:\n            data = self._parse_json(\n                self._search_regex(\n                    r'data-collection=([\"\\'])(?P<data>{.+?})\\1', webpage,\n                    'data collection', default='{}', group='data'),\n                display_id, transform_source=unescapeHTML, fatal=False)\n            video_id = self._extract_video_id(\n                data, lesson_id) or self._search_regex(","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/raywenderlich.py#L68-L104","documentation":"RayWenderlichIE._real_extract raises ExtractorError('This content is only available for subscribers', expected=True) when the downloaded lesson webpage contains the literal marker '>Subscribe to unlock'. raywenderlich.com (now Kodeco) gates most course lessons behind a paid subscription, and paid pages render that subscribe prompt instead of the lesson's video data (vimeo id or embedded JSON).","triggerScenarios":"Extracting any course lesson URL (videos.raywenderlich.com/lessons/<id> or courses/<course_id>/lessons/<lesson_id>) while not authenticated as an entitled subscriber; the check is a plain substring test on the HTML, so any page containing '>Subscribe to unlock' triggers it, even before the extractor looks for vimeo ids or subscriber-only JSON.","commonSituations":"Logged-out extraction of paid course content; cookies for a free account without an active subscription; free accounts hitting pro-content after a site redesign changed the marker string (older/whitespace variants of the marker can also false-negative, causing downstream parse errors instead).","solutions":["Authenticate with an active subscriber account — export cookies from a logged-in browser session and pass them via --cookies.","Confirm the lesson is actually subscriber-only; some free lessons extract fine without login.","Update youtube-dl if the marker string changed, so the gate is detected/rejected accurately.","For entitled sessions that still fail, verify the cookie export includes the raywenderlich auth cookies."],"exampleFix":"# before\nyoutube_dl 'https://videos.raywenderlich.com/courses/112/lessons/1'\n\n# after\nyoutube_dl --cookies kodeco-cookies.txt 'https://videos.raywenderlich.com/courses/112/lessons/1'","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    info = ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'only available for subscribers' in str(e):\n        retry_with_subscriber_cookies(url)","preventionTips":["Export cookies from an entitled subscriber session and pass via --cookies.","Keep the cookie file fresh — expired sessions re-trigger the paywall page.","Skip gated lessons in free-account batch runs instead of retrying."],"tags":["raywenderlich","paywall","subscription","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}