{"record":{"id":"fe58c1171edd039e","repo":"yt-dlp/yt-dlp","slug":"unsupported-language-code-preferred-lang-suppo","errorCode":null,"errorMessage":"Unsupported language code: {preferred_lang}. Supported language codes (case-sensitive): {join_nonempty(*self._SUPPORTED_LANG_CODES, delim=\", \")}.","messagePattern":"Unsupported language code: (.+?)\\. Supported language codes \\(case-sensitive\\): (.+?)\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"yt_dlp/extractor/youtube/_base.py","lineNumber":651,"sourceCode":"    def handle_from_url(self, url):\n        return self._search_regex(rf'^(?:https?://(?:www\\.)?youtube\\.com)?/({self._YT_HANDLE_RE})',\n                                  urllib.parse.unquote(url or ''), 'channel handle', default=None)\n\n    def ucid_from_url(self, url):\n        return self._search_regex(rf'^(?:https?://(?:www\\.)?youtube\\.com)?/({self._YT_CHANNEL_UCID_RE})',\n                                  url, 'channel id', default=None)\n\n    @functools.cached_property\n    def _preferred_lang(self):\n        \"\"\"\n        Returns a language code supported by YouTube for the user preferred language.\n        Returns None if no preferred language set.\n        \"\"\"\n        preferred_lang = self._configuration_arg('lang', ie_key='Youtube', casesense=True, default=[''])[0]\n        if not preferred_lang:\n            return\n        if preferred_lang not in self._SUPPORTED_LANG_CODES:\n            raise ExtractorError(\n                f'Unsupported language code: {preferred_lang}. Supported language codes (case-sensitive): {join_nonempty(*self._SUPPORTED_LANG_CODES, delim=\", \")}.',\n                expected=True)\n        elif preferred_lang != 'en':\n            self.report_warning(\n                f'Preferring \"{preferred_lang}\" translated fields. Note that some metadata extraction may fail or be incorrect.')\n        return preferred_lang\n\n    def _initialize_consent(self):\n        if self._has_auth_cookies:\n            return\n        socs = self._youtube_cookies.get('SOCS')\n        if socs and not socs.value.startswith('CAA'):  # not consented\n            return\n        self._set_cookie('.youtube.com', 'SOCS', 'CAI', secure=True)  # accept all (required for mixes)\n\n    def _initialize_pref(self):\n        pref_cookie = self._youtube_cookies.get('PREF')\n        pref = {}","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/yt-dlp/yt-dlp/blob/81ecd58b1394793e6da9998cc19fdb45657f1685/yt_dlp/extractor/youtube/_base.py#L633-L669","documentation":"YoutubeBaseInfoExtractor._preferred_lang (a functools.cached_property) validates the youtube:lang extractor argument against the hard-coded _SUPPORTED_LANG_CODES list using casesense=True. Any code not in that list aborts extraction immediately with expected=True, and the error message prints the full supported list. Codes like 'en', 'de', 'pt-PT', 'zh-CN', 'ja' are valid; near-misses like 'EN', 'pt-BR' (not listed), or 'zh' are not.","triggerScenarios":"Running any YouTube extraction while --extractor-args youtube:lang=CODE is set and CODE is misspelled, wrong case (the check is case-sensitive), or a variant the list does not contain (e.g. 'pt-BR', 'nb', 'zh'). The property is cached, so the very first URL touching it fails.","commonSituations":"Copy-pasting a locale from elsewhere (BCP-47 with wrong region), assuming case-insensitivity, using an OS locale name instead of YouTube's list, or running an old yt-dlp whose supported list predates newly added codes.","solutions":["Re-run with a code taken verbatim from the error message's supported list (e.g. youtube:lang=pt-PT, youtube:lang=zh-CN, youtube:lang=en-GB)","Check exact casing: 'en' not 'EN', 'zh-CN' not 'zh-cn'","Update yt-dlp; the supported-codes list changes over releases and newer builds may accept your code","Drop the lang argument entirely if you do not need translated metadata"],"exampleFix":"# before\nyt-dlp --extractor-args \"youtube:lang=pt-BR\" \"https://www.youtube.com/watch?v=...\"\n# -> Unsupported language code: pt-BR. ...\n\n# after\nyt-dlp --extractor-args \"youtube:lang=pt-PT\" \"https://www.youtube.com/watch?v=...\"","handlingStrategy":"validation","validationCode":"from yt_dlp.extractor.youtube._base import YoutubeBaseInfoExtractor\n\nlang = 'pt-PT'  # value you intend to pass as youtube:lang\nif lang not in YoutubeBaseInfoExtractor._SUPPORTED_LANG_CODES:\n    raise ValueError(\n        f'{lang!r} unsupported; pick one of: {YoutubeBaseInfoExtractor._SUPPORTED_LANG_CODES}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat youtube:lang values as case-sensitive exact tokens; copy them from the error message or the _SUPPORTED_LANG_CODES list in the installed version","Prefer whole-language codes ('pt', 'en') over regional variants unless you need the variant","Smoke-test new configs with --simulate before long runs"],"tags":["youtube","extractor-args","localization","configuration","case-sensitive"],"backgroundTag":"invalid-argument-value","analyzedSha":"81ecd58b1394793e6da9998cc19fdb45657f1685","analyzedAt":"2026-08-22T12:21:25.439Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}