crewAIInc/crewAI · error · ValueError
Invalid YouTube channel URL: {channel_url}
Error message
Invalid YouTube channel URL: {channel_url} What it means
ValueError from the YouTube channel loader's URL validation. It does simple substring matching: the URL must contain one of 'youtube.com/channel/', 'youtube.com/c/', 'youtube.com/@', or 'youtube.com/user/'. Anything else — including youtu.be links, plain watch URLs, or non-YouTube URLs — is rejected before any network call.
Source
Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/youtube_channel_loader.py:44
try:
from pytube import Channel # type: ignore[import-untyped]
except ImportError as e:
raise ImportError(
"YouTube channel support requires pytube. Install with: uv add pytube"
) from e
channel_url = source.source
if not any(
pattern in channel_url
for pattern in [
"youtube.com/channel/",
"youtube.com/c/",
"youtube.com/@",
"youtube.com/user/",
]
):
raise ValueError(f"Invalid YouTube channel URL: {channel_url}")
metadata: dict[str, Any] = {
"source": channel_url,
"data_type": "youtube_channel",
}
try:
channel = Channel(channel_url)
metadata["channel_name"] = channel.channel_name
metadata["channel_id"] = channel.channel_id
max_videos = kwargs.get("max_videos", 10)
video_urls = list(channel.video_urls)[:max_videos]
metadata["num_videos_loaded"] = len(video_urls)
metadata["total_videos"] = len(list(channel.video_urls))
content_parts = [View on GitHub (pinned to 754d7323be)
Solutions
- Use a canonical channel URL form: https://www.youtube.com/@handle, /channel/UC..., /c/CustomName, or /user/LegacyName.
- For single videos, use the YouTube video loader instead of the channel loader.
- Before loading, validate the URL contains one of the four accepted substrings yourself and route to the correct loader.
- If you only have a video ID or youtu.be link, expand it to the full watch URL first and use the video loader.
Example fix
# before loader.load(SourceContent(path="https://youtu.be/abc123")) # rejected # after loader.load(SourceContent(path="https://www.youtube.com/@somechannel"))
Defensive patterns
Strategy: validation
Validate before calling
CHANNEL_MARKERS = ("youtube.com/channel/", "youtube.com/c/", "youtube.com/@", "youtube.com/user/")
def is_channel_url(url: str) -> bool:
return any(m in url for m in CHANNEL_MARKERS) Try / catch
try:
result = channel_loader.load(src)
except ValueError as e:
if "Invalid YouTube channel URL" in str(e):
route_to_correct_loader(src) # video loader for watch/youtu.be links
raise Prevention
- Route watch?v=/youtu.be links to the video loader and only channel-form URLs here.
- Normalize to https://www.youtube.com/@handle before loading.
- Reject playlist URLs explicitly — neither loader supports them.
When it happens
Trigger: Passing a single video URL (youtube.com/watch?v=... or youtu.be/...), a playlist URL, a shorts URL, or a handle URL missing the '@' prefix. Note the check is literal substring matching, so even youtube.com/watch triggers 'invalid' despite being a valid YouTube page, and https://m.youtube.com/@name works only because '@' appears anywhere in the string.
Common situations: Users assume any YouTube URL works and pass video links to the channel loader; mobile youtu.be share links; URLs with the handle spelled without @; region-specific domains like youtube.co.uk.
Related errors
- Invalid YouTube URL: {video_url}
- Blocked unsafe {label}: {e}
- Blocked unsafe URL: {e}
- Client is not initialized
- Invalid data_type: '{raw_data_type}'. Valid values are: 'fil
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/77513c51fb70fe48.
Report an issue: GitHub.