crewAIInc/crewAI · error · ValueError
Invalid GitHub repository URL: {repo_url}
Error message
Invalid GitHub repository URL: {repo_url} What it means
Raised by GithubLoader.load() when the URL has the right prefix but does not contain at least two path segments (owner and repo). After stripping 'https://github.com/', the remainder is split on '/'; fewer than 2 parts means the URL names no repository, e.g. just the bare domain or only an owner.
Source
Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py:34
Args:
source: GitHub repository URL
**kwargs: Additional arguments including gh_token and content_types
Returns:
LoaderResult with repository content
"""
metadata = kwargs.get("metadata", {})
gh_token = metadata.get("gh_token")
content_types = metadata.get("content_types", ["code", "repo"])
repo_url = source.source
if not repo_url.startswith("https://github.com/"):
raise ValueError(f"Invalid GitHub URL: {repo_url}")
parts = repo_url.replace("https://github.com/", "").strip("/").split("/")
if len(parts) < 2:
raise ValueError(f"Invalid GitHub repository URL: {repo_url}")
repo_name = f"{parts[0]}/{parts[1]}"
g = Github(gh_token) if gh_token else Github()
try:
repo = g.get_repo(repo_name)
except GithubException as e:
raise ValueError(f"Unable to access repository {repo_name}: {e}") from e
all_content = []
if "repo" in content_types:
all_content.append(f"Repository: {repo.full_name}")
all_content.append(f"Description: {repo.description or 'No description'}")
all_content.append(f"Language: {repo.language or 'Not specified'}")
all_content.append(f"Stars: {repo.stargazers_count}")
all_content.append(f"Forks: {repo.forks_count}")View on GitHub (pinned to 754d7323be)
Solutions
- Fix the URL to include owner/repo: https://github.com/<owner>/<repo>.
- Validate the shape before loading with a regex like ^https://github\.com/[^/]+/[^/]+.
- If collecting from users, parse with urllib.parse and require exactly the two segments.
Example fix
# before
result = GithubLoader().load(SourceContent('https://github.com/crewAIInc')) # owner only
# after
import re
url = 'https://github.com/crewAIInc/crewAI'
assert re.fullmatch(r'https://github\.com/[^/]+/[^/]+', url), 'need owner/repo URL'
result = GithubLoader().load(SourceContent(url)) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse\n\ndef has_owner_repo(url: str) -> bool:\n parts = [p for p in urlparse(url).path.split('/') if p]\n return len(parts) >= 2 Type guard
import re\n\ndef is_valid_repo_url(u: str) -> bool:\n return bool(re.fullmatch(r'https://github\.com/[^/]+/[^/]+', u))
Prevention
- Validate repo URLs with a regex before ingestion.
- Never template only part of owner/repo — require both fields.
- Reject bare profile links at input time.
When it happens
Trigger: Passing 'https://github.com', 'https://github.com/', or 'https://github.com/someowner' — anything without an owner/repo pair. Also triggered by URLs whose path is empty after strip('/'), like 'https://github.com//' (empty split parts).
Common situations: Users pasting their profile URL instead of a repo URL; templating bugs that drop the repo segment ('https://github.com/{owner}/'); trailing-slash or empty-string interpolation from config; URLs built from unvalidated user input where only the org was collected.
Related errors
- Invalid GitHub URL: {repo_url}
- URL directory loading is not supported. Please provide a loc
- Directory does not exist: {source_ref}
- Path is not a directory: {source_ref}
- No content could be loaded from repository: {repo_url}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/5ed097eb5e4522d4.
Report an issue: GitHub.