{"record":{"id":"5c63ec2a22017c2f","repo":"ytdl-org/youtube-dl","slug":"unable-to-login-s","errorCode":null,"errorMessage":"Unable to login: %s","messagePattern":"Unable to login: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/animeondemand.py","lineNumber":92,"sourceCode":"        post_url = self._search_regex(\n            r'<form[^>]+action=([\"\\'])(?P<url>.+?)\\1', login_page,\n            'post url', default=self._LOGIN_URL, group='url')\n\n        if not post_url.startswith('http'):\n            post_url = urljoin(self._LOGIN_URL, post_url)\n\n        response = self._download_webpage(\n            post_url, None, 'Logging in',\n            data=urlencode_postdata(login_form), headers={\n                'Referer': self._LOGIN_URL,\n            })\n\n        if all(p not in response for p in ('>Logout<', 'href=\"/users/sign_out\"')):\n            error = self._search_regex(\n                r'<p[^>]+\\bclass=([\"\\'])(?:(?!\\1).)*\\balert\\b(?:(?!\\1).)*\\1[^>]*>(?P<error>.+?)</p>',\n                response, 'error', default=None, group='error')\n            if error:\n                raise ExtractorError('Unable to login: %s' % error, expected=True)\n            raise ExtractorError('Unable to log in')\n\n    def _real_initialize(self):\n        self._login()\n\n    def _real_extract(self, url):\n        anime_id = self._match_id(url)\n\n        webpage = self._download_webpage(url, anime_id)\n\n        if 'data-playlist=' not in webpage:\n            self._download_webpage(\n                self._APPLY_HTML5_URL, anime_id,\n                'Activating HTML5 beta', 'Unable to apply HTML5 beta')\n            webpage = self._download_webpage(url, anime_id)\n\n        csrf_token = self._html_search_meta(\n            'csrf-token', webpage, 'csrf token', fatal=True)","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/animeondemand.py#L74-L110","documentation":"Raised by the AnimeOnDemand login flow when the POST response lacks both '>Logout<' and 'href=\"/users/sign_out\"' and an alert-styled <p> error was scraped from the page. The scraped alert text (German site messages like 'E-Mail oder Passwort falsch') is embedded into the message. Marked expected=True.","triggerScenarios":"POST to the login form URL returns a page without logout markers; regex finds class containing 'alert' with inner text, e.g. wrong credentials or account restrictions; Devise/Rails login errors surfaced as alert paragraphs.","commonSituations":"Wrong --username/--password; account without an active Anime-on-Demand subscription; site markup change altering the alert class so only the generic 'Unable to log in' appears instead.","solutions":["Verify credentials by logging in at anime-on-demand.de in a browser","Confirm the subscription is active — locked accounts often produce alert errors on login POST","If login works in the browser but not here, the alert markup likely changed; check upstream extractor updates"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'Unable to login' in str(e):\n        # e.msg carries the German alert text; 'Unable to log in' (no colon) means markup changed\n        prompt_relogin('animeondemand', detail=str(e))","preventionTips":["Verify the AnimeOnDemand subscription is active before automating — locked accounts fail at login POST","Distinguish the two variants: 'Unable to login: <alert>' = credentials; bare 'Unable to log in' = site markup changed"],"tags":["animeondemand","authentication","login","credentials"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}