ytdl-org/youtube-dl · warning · ExtractorError
Test case %d not found, got only %d tests
Error message
Test case %d not found, got only %d tests
What it means
Raised by the testurl extractor when the optional /<num> index in testurl:<extractor>/<num> is out of range: after collecting the extractor's _TEST (singular) plus all _TESTS entries, testcases[num] raised IndexError. The error reports the requested index and how many tests actually exist. Marked expected=True.
Source
Thrown at youtube_dl/extractor/testurl.py:57
('Found multiple matching extractors: %s' %
' '.join(ie.IE_NAME for ie in matching_extractors)),
expected=True)
else:
extractor = matching_extractors[0]
num_str = mobj.group('num')
num = int(num_str) if num_str else 0
testcases = []
t = getattr(extractor, '_TEST', None)
if t:
testcases.append(t)
testcases.extend(getattr(extractor, '_TESTS', []))
try:
tc = testcases[num]
except IndexError:
raise ExtractorError(
('Test case %d not found, got only %d tests' %
(num, len(testcases))),
expected=True)
self.to_screen('Test URL: %s' % tc['url'])
return self.url_result(tc['url'], video_id=video_id)
View on GitHub (pinned to 956b8c5855)
Solutions
- Use a smaller index: the message states 'got only %d tests', so valid indices are 0..that-1.
- Omit the index entirely (testurl:<name>) to get the extractor's primary test case.
- Regenerate any hard-coded indices after upgrading youtube-dl, since test lists change between versions.
Example fix
# before (5 tests => indices 0..4) # youtube-dl testurl:someextractor/5 # after # youtube-dl testurl:someextractor/4 # or simply: # youtube-dl testurl:someextractor
Defensive patterns
Strategy: validation
Validate before calling
# Determine how many tests an extractor exposes before choosing an index
ie = next(e for e in gen_extractors() if e.IE_NAME.lower() == name.lower())
count = (1 if getattr(ie, '_TEST', None) else 0) + len(getattr(ie, '_TESTS', []))
if not 0 <= num < count:
print('index %d out of range; valid: 0..%d' % (num, count - 1)) Type guard
def valid_test_index(ie, num):
"""True when num indexes into the extractor's collected test cases."""
total = (1 if getattr(ie, '_TEST', None) else 0) + len(getattr(ie, '_TESTS', []))
return isinstance(num, int) and 0 <= num < total Try / catch
try:
ydl.extract_info('testurl:%s/%d' % (name, num))
except ExtractorError as e:
if e.expected and 'not found, got only' in str(e):
num = 0 # fall back to the primary test case
ydl.extract_info('testurl:%s' % name)
else:
raise Prevention
- Indices are 0-based; with N tests the max valid index is N-1.
- Omit the index to always get the extractor's primary test case.
- Recompute hard-coded indices after every youtube-dl upgrade.
When it happens
Trigger: A URL like testurl:youtube/99 when the matched extractor has fewer than 100 test cases; note indices are 0-based, so testurl:<name>/<N> fails once N >= number of tests (num defaults to 0 when omitted).
Common situations: Off-by-one confusion (asking for test 5 on an extractor with 5 tests — valid indices are 0..4); hard-coded test indices in scripts that break when an extractor's _TESTS list shrinks in a new release.
Related errors
- No extractors matching %r found
- Found multiple matching extractors: %s
- %s said: %s
- Unable to login: %s
- lynda returned error: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/c07493252d09f68f.
Report an issue: GitHub.