{"record":{"id":"c3ee51d5c462b5ff","repo":"crewAIInc/crewAI","slug":"invalid-github-url-repo-url","errorCode":null,"errorMessage":"Invalid GitHub URL: {repo_url}","messagePattern":"Invalid GitHub URL: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py","lineNumber":30,"sourceCode":"    \"\"\"Loader for GitHub repository content.\"\"\"\n\n    def load(self, source: SourceContent, **kwargs: Any) -> LoaderResult:  # type: ignore[override]\n        \"\"\"Load content from a GitHub repository.\n\n        Args:\n            source: GitHub repository URL\n            **kwargs: Additional arguments including gh_token and content_types\n\n        Returns:\n            LoaderResult with repository content\n        \"\"\"\n        metadata = kwargs.get(\"metadata\", {})\n        gh_token = metadata.get(\"gh_token\")\n        content_types = metadata.get(\"content_types\", [\"code\", \"repo\"])\n\n        repo_url = source.source\n        if not repo_url.startswith(\"https://github.com/\"):\n            raise ValueError(f\"Invalid GitHub URL: {repo_url}\")\n\n        parts = repo_url.replace(\"https://github.com/\", \"\").strip(\"/\").split(\"/\")\n        if len(parts) < 2:\n            raise ValueError(f\"Invalid GitHub repository URL: {repo_url}\")\n\n        repo_name = f\"{parts[0]}/{parts[1]}\"\n\n        g = Github(gh_token) if gh_token else Github()\n\n        try:\n            repo = g.get_repo(repo_name)\n        except GithubException as e:\n            raise ValueError(f\"Unable to access repository {repo_name}: {e}\") from e\n\n        all_content = []\n\n        if \"repo\" in content_types:\n            all_content.append(f\"Repository: {repo.full_name}\")","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Normalize the URL before loading: prepend https:// if missing, and convert git@github.com:owner/repo.git to https://github.com/owner/repo.","If the repo is on GitLab/Bitbucket, this loader cannot fetch it — use a different ingestion path (clone locally and use DirectoryLoader).","Validate user-supplied URLs with a regex/parser before handing them to the loader."],"exampleFix":"# before\nresult = GithubLoader().load(SourceContent('github.com/crewAIInc/crewAI'))  # no scheme\n\n# after\nimport re\nurl = 'github.com/crewAIInc/crewAI'\nif url.startswith('git@github.com:'):\n    url = 'https://github.com/' + url.split(':', 1)[1].removesuffix('.git')\nelif not url.startswith('https://'):\n    url = 'https://' + url\nresult = GithubLoader().load(SourceContent(url))","handlingStrategy":"validation","validationCode":"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","typeGuard":"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))","tryCatchPattern":null,"preventionTips":["Normalize SSH/scheme-less forms centrally before any loader call.","Reject non-GitHub forges early with a clear message.","Store canonical https URLs in config, not git remotes."],"tags":["github","validation","loader","rag"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}