yt-dlp/yt-dlp · error · ExtractorError
Invalid extractor-arg "tab". Must be one of {", ".join(self.
Error message
Invalid extractor-arg "tab". Must be one of {", ".join(self._TABS)} What it means
Rokfin's channel extractor validates the 'tab' extractor-arg in _validate_extractor_args before any network request: the argument must be a single value from the allowed set (the _TABS keys: videos, podcasts, streams, stacks). Passing more than one tab or an unknown name raises this immediately with expected=True.
Source
Thrown at yt_dlp/extractor/rokfin.py:355
},
}]
_TABS = {
'new': 'posts',
'top': 'top',
'videos': 'video',
'podcasts': 'audio',
'streams': 'stream',
'stacks': 'stack',
}
def _real_initialize(self):
self._validate_extractor_args()
def _validate_extractor_args(self):
requested_tabs = self._configuration_arg('tab', None)
if requested_tabs is not None and (len(requested_tabs) > 1 or requested_tabs[0] not in self._TABS):
raise ExtractorError(f'Invalid extractor-arg "tab". Must be one of {", ".join(self._TABS)}', expected=True)
def _entries(self, channel_id, channel_name, tab):
pages_total = None
for page_n in itertools.count(0):
if tab in ('posts', 'top'):
data_url = f'{_API_BASE_URL}user/{channel_name}/{tab}?page={page_n}&size=50'
else:
data_url = f'{_API_BASE_URL}post/search/{tab}?page={page_n}&size=50&creator={channel_id}'
metadata = self._download_json(
data_url, channel_name,
note=f'Downloading video metadata page {page_n + 1}{format_field(pages_total, None, " of %s")}')
yield from self._get_video_data(metadata)
pages_total = int_or_none(metadata.get('totalPages')) or None
is_last = metadata.get('last')
if is_last or (page_n > pages_total if pages_total else is_last is not False):
return
View on GitHub (pinned to 81ecd58b13)
Solutions
- Use exactly one allowed value: --extractor-args 'rokfinchannel:tab=videos' (or podcasts, streams, stacks)
- Pass only one tab per invocation; run the command again for each additional tab
- Check the value against the allowed list printed in the error message itself
- Update yt-dlp — new tabs are added to _TABS over time
Example fix
# before yt-dlp --extractor-args "rokfinchannel:tab=videos;tab=streams" "https://rokfin.com/@Styxhexenhammer666" # after yt-dlp --extractor-args "rokfinchannel:tab=videos" "https://rokfin.com/@Styxhexenhammer666" yt-dlp --extractor-args "rokfinchannel:tab=streams" "https://rokfin.com/@Styxhexenhammer666"
Defensive patterns
Strategy: validation
Validate before calling
ROKFIN_TABS = ('videos', 'podcasts', 'streams', 'stacks')
def build_rokfin_args(tabs):
assert len(tabs) == 1, 'pass exactly one tab'
assert tabs[0] in ROKFIN_TABS, f'tab must be one of {ROKFIN_TABS}'
return ['--extractor-args', f'rokfinchannel:tab={tabs[0]}'] Type guard
def is_valid_rokfin_tab(tab: str) -> bool:
return tab in {'videos', 'podcasts', 'streams', 'stacks'} Prevention
- Take allowed tab values from the extractor source/docs (_TABS), not from the website nav
- Pass a single tab= per invocation and loop over tabs in your script
- Whitelist extractor-args in wrappers that forward user input
When it happens
Trigger: Invoking a https://rokfin.com/@<channel> URL with --extractor-args where tab is repeated ('tab=videos;tab=streams' yields len > 1) or the value is not in _TABS (e.g. 'tab=all', 'tab=top', 'tab=live').
Common situations: Guessing tab names from the website navigation; copy-pasting multi-value extractor-arg syntax from other extractors; shell quoting that splits the argument into multiple values; scripts templating tab names from user input.
Related errors
- Invalid bitrate(s): {", ".join(invalid_bitrates)}. Valid bit
- '{selected_api}' is not a valid API selection
- Unsupported API client "{client}" requested. Supported clien
- Unsupported language code: {preferred_lang}. Supported langu
- No player clients have been requested
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/c73c12b505cc7d04.
Report an issue: GitHub.