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

  1. Fix the URL to include owner/repo: https://github.com/<owner>/<repo>.
  2. Validate the shape before loading with a regex like ^https://github\.com/[^/]+/[^/]+.
  3. 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

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


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/5ed097eb5e4522d4. Report an issue: GitHub.