{"record":{"id":"fc81a7b01c82086d","repo":"ytdl-org/youtube-dl","slug":"found-multiple-matching-extractors-s","errorCode":null,"errorMessage":"Found multiple matching extractors: %s","messagePattern":"Found multiple matching extractors: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"warning","filePath":"youtube_dl/extractor/testurl.py","lineNumber":38,"sourceCode":"        extractor_id = mobj.group('extractor')\n        all_extractors = gen_extractors()\n\n        rex = re.compile(extractor_id, flags=re.IGNORECASE)\n        matching_extractors = [\n            e for e in all_extractors if rex.search(e.IE_NAME)]\n\n        if len(matching_extractors) == 0:\n            raise ExtractorError(\n                'No extractors matching %r found' % extractor_id,\n                expected=True)\n        elif len(matching_extractors) > 1:\n            # Is it obvious which one to pick?\n            try:\n                extractor = next(\n                    ie for ie in matching_extractors\n                    if ie.IE_NAME.lower() == extractor_id.lower())\n            except StopIteration:\n                raise ExtractorError(\n                    ('Found multiple matching extractors: %s' %\n                        ' '.join(ie.IE_NAME for ie in matching_extractors)),\n                    expected=True)\n        else:\n            extractor = matching_extractors[0]\n\n        num_str = mobj.group('num')\n        num = int(num_str) if num_str else 0\n\n        testcases = []\n        t = getattr(extractor, '_TEST', None)\n        if t:\n            testcases.append(t)\n        testcases.extend(getattr(extractor, '_TESTS', []))\n\n        try:\n            tc = testcases[num]\n        except IndexError:","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/testurl.py#L20-L56","documentation":"Raised by the testurl extractor when the user-supplied case-insensitive regex matches MORE THAN one extractor IE_NAME and none of them matches the pattern exactly (case-insensitive equality). The names of all matches are listed in the error. Marked expected=True.","triggerScenarios":"A testurl:<pattern> URL where the pattern is a substring of several extractor names (e.g. 'tube' matching many '*tube*' IEs) and is not exactly equal to any single IE_NAME.","commonSituations":"Overly broad patterns like testurl:tube or testurl:music; users unaware the pattern is a regex matched against every IE_NAME.","solutions":["Use the exact extractor name: youtube-dl --list-extractors, then pass that name verbatim, e.g. testurl:ExactName (exact case-insensitive match disambiguates automatically).","Anchor the regex if you intended one extractor: testurl:^vimeo$.","Read the listed candidate names in the error message and pick one."],"exampleFix":"# before (ambiguous, matches many)\n# youtube-dl testurl:tube\n# after (exact single match)\n# youtube-dl --list-extractors | grep -ix 'vimeo'\n# youtube-dl testurl:vimeo","handlingStrategy":"validation","validationCode":"import subprocess, re\nnames = subprocess.run(['youtube-dl', '--list-extractors'], capture_output=True, text=True).stdout.splitlines()\nhits = [n for n in names if re.search(pattern, n, re.IGNORECASE)]\nif len(hits) > 1 and not any(n.lower() == pattern.lower() for n in hits):\n    print('ambiguous pattern; candidates:', hits)","typeGuard":"def unambiguous(pattern, names):\n    \"\"\"Return the single extractor for a testurl pattern, else None.\"\"\"\n    hits = [n for n in names if re.search(pattern, n, re.IGNORECASE)]\n    if len(hits) == 1:\n        return hits[0]\n    exact = [n for n in hits if n.lower() == pattern.lower()]\n    return exact[0] if len(exact) == 1 else None","tryCatchPattern":"try:\n    ydl.extract_info('testurl:%s' % pattern)\nexcept ExtractorError as e:\n    if e.expected and 'multiple matching extractors' in str(e):\n        pick_exact_name_from(e)   # candidates are listed in the message\n    raise","preventionTips":["Use exact extractor names or anchored regexes (^name$) for testurl.","Check candidate lists in the error message before retrying.","Avoid substrings like 'tube'/'music' that hit many IE_NAMEs."],"tags":["test-utility","user-input","ambiguity","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}