{"record":{"id":"256007097f147075","repo":"ytdl-org/youtube-dl","slug":"lynda-returned-error-s","errorCode":null,"errorMessage":"lynda returned error: %s","messagePattern":"lynda returned error: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/lynda.py","lineNumber":186,"sourceCode":"                    })\n            self._sort_formats(formats)\n\n            conviva = self._download_json(\n                'https://www.lynda.com/ajax/player/conviva', video_id,\n                'Downloading conviva JSON', query=query)\n\n            return {\n                'id': video_id,\n                'title': conviva['VideoTitle'],\n                'description': conviva.get('VideoDescription'),\n                'release_year': int_or_none(conviva.get('ReleaseYear')),\n                'duration': int_or_none(conviva.get('Duration')),\n                'creator': conviva.get('Author'),\n                'formats': formats,\n            }\n\n        if 'Status' in video:\n            raise ExtractorError(\n                'lynda returned error: %s' % video['Message'], expected=True)\n\n        if video.get('HasAccess') is False:\n            self._raise_unavailable(video_id)\n\n        video_id = compat_str(video.get('ID') or video_id)\n        duration = int_or_none(video.get('DurationInSeconds'))\n        title = video['Title']\n\n        formats = []\n\n        fmts = video.get('Formats')\n        if fmts:\n            formats.extend([{\n                'url': f['Url'],\n                'ext': f.get('Extension'),\n                'width': int_or_none(f.get('Width')),\n                'height': int_or_none(f.get('Height')),","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/lynda.py#L168-L204","documentation":"Raised by LyndaIE when the single-video API response contains a 'Status' key, which Lynda only includes when the request failed. The message embeds video['Message'], Lynda's own description of the failure (e.g. 'Video not found'). Marked expected=True because it maps a well-formed service error to a user-visible message.","triggerScenarios":"GET of the lynda.com video REST endpoint returns JSON whose top-level object has a truthy/any 'Status' key; the very next line's HasAccess check is never reached because the raise happens first.","commonSituations":"Downloading a video id that was removed or unpublished; a course video whose id was scraped from a stale playlist page; an account without entitlement seeing Status-based refusals; API version changes making previously silent errors visible.","solutions":["Read the embedded Message text; it states Lynda's reason (most often that the video id does not exist).","Confirm the video id by opening the lynda.com URL in a browser; if it 404s there, the id is dead.","Log in with entitled credentials (--username/--password or --cookies) if the video requires a subscription.","Update youtube-dl in case the video endpoint changed, then retry with -v to capture the raw response."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def lynda_video_has_error(video_json):\n    return isinstance(video_json, dict) and 'Status' in video_json","tryCatchPattern":"try:\n    info = ydl.extract_info(url, download=False)\nexcept ExtractorError as e:\n    if 'lynda returned error' in str(e):\n        msg = str(e).rsplit(':', 1)[1].strip()  # e.g. 'Video not found'\n        log_skip(url, msg)  # treat as dead resource, continue batch\n    else:\n        raise","preventionTips":["Validate video ids against the course listing before downloading individual videos.","Use entitled credentials so Status-based access refusals cannot occur.","Treat 'lynda returned error' as a permanent skip, not a retryable failure."],"tags":["api-response","video-unavailable","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}