{"record":{"id":"f7f47281b76db78b","repo":"yt-dlp/yt-dlp","slug":"this-video-is-password-protected-use-the-video","errorCode":null,"errorMessage":"This video is password-protected, use the --video-password option","messagePattern":"This video is password-protected, use the --video-password option","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"yt_dlp/extractor/loom.py","lineNumber":369,"sourceCode":"        subs_data = self._call_graphql_api(\n            'FetchVideoTranscript', video_id, 'Downloading GraphQL subtitles JSON', fatal=False)\n        return filter_dict({\n            'en': traverse_obj(subs_data, (\n                'data', 'fetchVideoTranscript',\n                ('source_url', 'captions_source_url'), {\n                    'url': {url_or_none},\n                })) or None,\n        })\n\n    def _real_extract(self, url):\n        video_id = self._match_id(url)\n        metadata = traverse_obj(\n            self._call_graphql_api('GetVideoSSR', video_id, 'Downloading GraphQL metadata JSON', fatal=False),\n            ('data', 'getVideo', {dict})) or {}\n\n        if metadata.get('__typename') == 'VideoPasswordMissingOrIncorrect':\n            if not self.get_param('videopassword'):\n                raise ExtractorError(\n                    'This video is password-protected, use the --video-password option', expected=True)\n            raise ExtractorError('Invalid video password', expected=True)\n\n        video_data = self._call_graphql_api(\n            'GetVideoSource', video_id, 'Downloading GraphQL video JSON')\n        chapter_data = self._call_graphql_api(\n            'FetchChapters', video_id, 'Downloading GraphQL chapters JSON', fatal=False)\n        duration = traverse_obj(metadata, ('video_properties', 'duration', {int_or_none}))\n\n        return {\n            'id': video_id,\n            'duration': duration,\n            'chapters': self._extract_chapters_from_description(\n                traverse_obj(chapter_data, ('data', 'fetchVideoChapters', 'content', {str})), duration) or None,\n            'formats': self._extract_formats(video_id, metadata, video_data),\n            'subtitles': self.extract_subtitles(video_id),\n            **traverse_obj(metadata, {\n                'title': ('name', {str}),","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/yt-dlp/yt-dlp/blob/81ecd58b1394793e6da9998cc19fdb45657f1685/yt_dlp/extractor/loom.py#L351-L387","documentation":"Loom's GraphQL endpoint GetVideoSSR returns an object whose __typename is 'VideoPasswordMissingOrIncorrect' for password-protected videos. When no password was supplied at all (get_param('videopassword') is falsy), the extractor raises this expected error telling you to pass --video-password. The video's owner set an access password; without it, metadata and sources are not served.","triggerScenarios":"Extracting a loom.com/share/<id> URL for a password-protected video without the videopassword option/parameter set.","commonSituations":"Team/shared Loom links with password protection; CI pipelines or bots hitting protected share URLs; forgetting that the -p/--video-password flag (not -a/--password) is the right one for media passwords.","solutions":["Obtain the password from the video owner and supply it: yt-dlp --video-password SECRET 'https://www.loom.com/share/<id>'","In the Python API, set 'videopassword': 'SECRET' in the YoutubeDL options dict","In interactive tools, catch this error, prompt the user, and retry with the password"],"exampleFix":"# before\nyt-dlp 'https://www.loom.com/share/abc123'\n# -> ExtractorError: This video is password-protected, use the --video-password option\n\n# after\nyt-dlp --video-password 'hunter2' 'https://www.loom.com/share/abc123'\n\n# Python API equivalent\nimport yt_dlp\nopts = {'videopassword': 'hunter2'}\nwith yt_dlp.YoutubeDL(opts) as ydl:\n    ydl.extract_info(url, download=True)","handlingStrategy":"retry","validationCode":null,"typeGuard":"def is_loom_password_needed(err) -> bool:\n    from yt_dlp.utils import ExtractorError\n    return isinstance(err, ExtractorError) and 'password-protected, use the --video-password option' in str(err)","tryCatchPattern":"import yt_dlp\nfrom yt_dlp.utils import ExtractorError\n\nurl = 'https://www.loom.com/share/abc123'\ntry:\n    with yt_dlp.YoutubeDL() as ydl:\n        info = ydl.extract_info(url, download=True)\nexcept ExtractorError as e:\n    if 'password-protected' not in str(e):\n        raise\n    pw = ask_user_for_password()              # or fetch from your secret store\n    with yt_dlp.YoutubeDL({'videopassword': pw}) as ydl:\n        info = ydl.extract_info(url, download=True)","preventionTips":["Collect video passwords up front for known-protected Loom links and pass the videopassword option","Remember the flag is --video-password (-p for media), not --password (account)","In pipelines, prompt-and-retry once on this message instead of failing the whole job"],"tags":["loom","password-protected","videopassword","access-control","expected-error"],"backgroundTag":"password-protected-media","analyzedSha":"81ecd58b1394793e6da9998cc19fdb45657f1685","analyzedAt":"2026-08-22T12:21:25.439Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}