crewAIInc/crewAI · error · ValueError

Invalid GitHub URL: {repo_url}

Error message

Invalid GitHub URL: {repo_url}

What it means

Raised by GithubLoader.load() when the source string does not start with 'https://github.com/'. The loader only supports that exact scheme+host prefix — no http://, no git@ SSH form, no api.github.com, no trailing variations — so any other URL shape is rejected before parsing owner/repo.

Source

Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py:30

    """Loader for GitHub repository content."""

    def load(self, source: SourceContent, **kwargs: Any) -> LoaderResult:  # type: ignore[override]
        """Load content from a GitHub repository.

        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}")

View on GitHub (pinned to 754d7323be)

Solutions

  1. Normalize the URL before loading: prepend https:// if missing, and convert git@github.com:owner/repo.git to https://github.com/owner/repo.
  2. If the repo is on GitLab/Bitbucket, this loader cannot fetch it — use a different ingestion path (clone locally and use DirectoryLoader).
  3. Validate user-supplied URLs with a regex/parser before handing them to the loader.

Example fix

# before
result = GithubLoader().load(SourceContent('github.com/crewAIInc/crewAI'))  # no scheme

# after
import re
url = 'github.com/crewAIInc/crewAI'
if url.startswith('git@github.com:'):
    url = 'https://github.com/' + url.split(':', 1)[1].removesuffix('.git')
elif not url.startswith('https://'):
    url = 'https://' + url
result = GithubLoader().load(SourceContent(url))
Defensive patterns

Strategy: validation

Validate before calling

import re\n\ndef normalize_github_url(url: str) -> str:\n    url = url.strip().removesuffix('.git')\n    if url.startswith('git@github.com:'):\n        url = 'https://github.com/' + url.split(':', 1)[1]\n    if not url.startswith('https://'):\n        url = 'https://' + url\n    return url

Type guard

GITHUB_REPO_RE = re.compile(r'^https://github\.com/[^/]+/[^/]+/?$')\n\ndef is_github_repo_url(url: str) -> bool:\n    return bool(GITHUB_REPO_RE.match(url))

Prevention

When it happens

Trigger: Passing 'github.com/owner/repo' (missing scheme), 'http://github.com/owner/repo', 'git@github.com:owner/repo.git', or an entirely different host like a GitLab or Gitea URL.

Common situations: Copy-pasting repo URLs that browsers display without the scheme; supporting arbitrary forge URLs in user-facing config where users enter GitLab/Bitbucket links; config files storing SSH remotes from git remote -v output.

Related errors


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