{"record":{"id":"5ed097eb5e4522d4","repo":"crewAIInc/crewAI","slug":"invalid-github-repository-url-repo-url","errorCode":null,"errorMessage":"Invalid GitHub repository URL: {repo_url}","messagePattern":"Invalid GitHub repository URL: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py","lineNumber":34,"sourceCode":"\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}\")\n            all_content.append(f\"Description: {repo.description or 'No description'}\")\n            all_content.append(f\"Language: {repo.language or 'Not specified'}\")\n            all_content.append(f\"Stars: {repo.stargazers_count}\")\n            all_content.append(f\"Forks: {repo.forks_count}\")","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/github_loader.py#L16-L52","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"# before\nresult = GithubLoader().load(SourceContent('https://github.com/crewAIInc'))  # owner only\n\n# after\nimport re\nurl = 'https://github.com/crewAIInc/crewAI'\nassert re.fullmatch(r'https://github\\.com/[^/]+/[^/]+', url), 'need owner/repo URL'\nresult = GithubLoader().load(SourceContent(url))","handlingStrategy":"validation","validationCode":"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","typeGuard":"import re\\n\\ndef is_valid_repo_url(u: str) -> bool:\\n    return bool(re.fullmatch(r'https://github\\.com/[^/]+/[^/]+', u))","tryCatchPattern":null,"preventionTips":["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."],"tags":["github","validation","loader","rag"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}