datawhalechina/hello-agents · error · ValueError
无法解析 GitHub URL: {url}
Error message
无法解析 GitHub URL: {url} What it means
ValueError raised by RepoAnalyzer._parse_github_url when the URL, after stripping '.git' and trailing slashes, does not contain at least two slash-separated tail segments. The naive split-based parser has real holes: it accepts any string whose last two '/'-segments exist (e.g. 'not a url/owner/repo' or 'https://gitlab.com/o/r'), and url.rstrip('.git') strips the character set {.g,i,t} not the suffix — so a repo ending in 'g', 'i', 't', or combinations like 'agent' loses characters.
Source
Thrown at Co-creation-projects/Yixiang-Wu-LearningAgent/specialist/repo_analyzer.py:58
从 GitHub URL 提取 owner 和 repo 名称
Args:
url: GitHub URL(如 https://github.com/vuejs/core)
Returns:
(owner, repo) 元组
"""
# 去掉 .git 后缀
url = url.rstrip(".git")
# 提取 owner 和 repo
parts = url.rstrip("/").split("/")
if len(parts) >= 2:
owner = parts[-2]
repo = parts[-1]
return owner, repo
raise ValueError(f"无法解析 GitHub URL: {url}")
def _fetch_repo_info(self, owner: str, repo: str) -> Dict:
"""
获取仓库基本信息
Args:
owner: 仓库所有者
repo: 仓库名称
Returns:
仓库信息字典
"""
url = f"{self.GITHUB_API_BASE}/repos/{owner}/{repo}"
response = requests.get(url, headers=self.headers, timeout=10)
response.raise_for_status()
return response.json()
def _fetch_readme(self, owner: str, repo: str) -> Optional[str]:View on GitHub (pinned to 606a07d341)
Solutions
- Replace rstrip('.git') with a real suffix removal: if url.endswith('.git'): url = url[:-4]
- Parse with a regex or urllib.parse that handles https://, http://, and git@github.com:owner/repo.git forms explicitly
- Validate owner/repo against GitHub's charset ([A-Za-z0-9_.-]) after parsing
- Raise with the original unmodified URL in the message so the user sees what was rejected
Example fix
# before
url = url.rstrip(".git")
parts = url.rstrip("/").split("/")
if len(parts) >= 2:
owner, repo = parts[-2], parts[-1]
return owner, repo
raise ValueError(f"无法解析 GitHub URL: {url}")
# after
import re
m = re.search(
r"(?:github\.com[:/])([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+?)(?:\.git)?/?$",
url,
)
if not m:
raise ValueError(f"无法解析 GitHub URL: {url!r},"
"期望形如 https://github.com/owner/repo(.git)")
return m.group(1), m.group(2) Defensive patterns
Strategy: validation
Validate before calling
import re
GH_RE = re.compile(
r"(?:https?://)?(?:www\.)?github\.com/"
r"([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+?)(?:\.git)?/?$"
)
def parse_github_url(url: str) -> tuple[str, str] | None:
m = GH_RE.search(url.strip())
return (m.group(1), m.group(2)) if m else None Type guard
from typing import Optional, Tuple
def is_github_repo_url(url: str) -> bool:
return isinstance(url, str) and bool(
re.search(r"github\.com[:/][A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+", url)
) Try / catch
owner_repo = parse_github_url(url)
if owner_repo is None:
raise ValueError(f"not a GitHub repo URL: {url!r}")
# no try/except needed — validation replaces the exception path Prevention
- Validate URL shape before calling the analyzer; prefer a regex covering https and git@ SSH forms
- Never strip suffixes with rstrip — it removes character sets, not suffixes
- Fuzz-test the parser with bare names, SSH URLs, and trailing '/tree/main' variants
When it happens
Trigger: Passing a bare repo name 'owner/repo' still works, but 'myrepo' alone (one segment) raises; SSH form 'git@github.com:owner/repo.git' is mangled because there is no '/' before the colon-joined tail — split gives ['git@github.com:owner', 'repo'] which parses but yields owner 'git@github.com:owner'; rstrip('.git') truncating repos like 'fastapi.git' fine but 'torch' -> 'torc', 'langchain' -> 'langchain' (ends 'n' ok) yet 'kgit' -> 'kg'; URL like 'https://github.com/owner' (single segment after domain is merged) raises.
Common situations: LLM-generated or user-typed URLs in noncanonical shapes (SSH clone URLs, missing scheme, trailing '/tree/main'); repos whose names end in g/i/t characters; copy-paste from git clone output.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/15f8d94f339147c2.
Report an issue: GitHub.