{"record":{"id":"e1c02632da3cc20b","repo":"ytdl-org/youtube-dl","slug":"clean-html-error-message","errorCode":null,"errorMessage":"clean_html(error_message)","messagePattern":"clean_html\\(error_message\\)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/teamtreehouse.py","lineNumber":71,"sourceCode":"\n    def _real_initialize(self):\n        email, password = self._get_login_info()\n        if email is None:\n            return\n\n        signin_page = self._download_webpage(\n            'https://teamtreehouse.com/signin',\n            None, 'Downloading signin page')\n        data = self._form_hidden_inputs('new_user_session', signin_page)\n        data.update({\n            'user_session[email]': email,\n            'user_session[password]': password,\n        })\n        error_message = get_element_by_class('error-message', self._download_webpage(\n            'https://teamtreehouse.com/person_session',\n            None, 'Logging in', data=urlencode_postdata(data)))\n        if error_message:\n            raise ExtractorError(clean_html(error_message), expected=True)\n\n    def _real_extract(self, url):\n        display_id = self._match_id(url)\n        webpage = self._download_webpage(url, display_id)\n        title = self._html_search_meta(['og:title', 'twitter:title'], webpage)\n        description = self._html_search_meta(\n            ['description', 'og:description', 'twitter:description'], webpage)\n        entries = self._parse_html5_media_entries(url, webpage, display_id)\n        if entries:\n            info = entries[0]\n\n            for subtitles in info.get('subtitles', {}).values():\n                for subtitle in subtitles:\n                    subtitle['ext'] = determine_ext(subtitle['url'], 'srt')\n\n            is_preview = 'data-preview=\"true\"' in webpage\n            if is_preview:\n                self.report_warning(","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/teamtreehouse.py#L53-L89","documentation":"Raised by TeamTreeHouseIE._login after posting credentials to teamtreehouse.com/person_session: the response contains an element with class 'error-message', whose HTML is cleaned and raised verbatim (expected=True). This is the site telling you why the sign-in failed — typically 'Invalid email or password'.","triggerScenarios":"Calling the extractor with --username/--password or netrc credentials that Treehouse rejects; the sign-in POST response renders the Rails error-message div.","commonSituations":"Wrong/stale password; subscription lapsed so login is refused; accounts with SSO login that cannot authenticate via the form; password managers storing outdated netrc lines.","solutions":["Read the cleaned message text — it states the exact refusal reason from Treehouse.","Verify the same credentials work at teamtreehouse.com/signin in a browser; reset the password if not.","Update .netrc with the working credentials (machine teamtreehouse.com).","If the account uses SSO only, log in via browser, export cookies, and pass --cookies instead of CLI login."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Practical pre-check: confirm creds work in a browser; programmatic\n# pre-validation is a login attempt itself, so rely on the error text","typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if e.expected and 'sign' not in str(e):  # login-stage expected errors\n        log.error('Treehouse login refused: %s', str(e))  # site's own message\n        prompt_password_reset()\n    else:\n        raise","preventionTips":["Keep .netrc credentials for teamtreehouse.com current; message text states the exact refusal.","Reset password via the website if credentials are stale.","SSO-only accounts: use --cookies instead of CLI login."],"tags":["login","credentials","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}