nikivdev/code · error
unable to parse GitHub repo from: {}
Error message
unable to parse GitHub repo from: {} What it means
After deriving the path portion of a GitHub reference, parse_github_repo splits it on '/' expecting an owner and a repo name. If the first or second segment is missing/empty (e.g. input reduced to just "owner" or "owner/"), it bails because a GitHub repository requires both parts.
Source
Thrown at src/repos.rs:1747
} else if let Some(idx) = trimmed.find("github.com/") {
&trimmed[idx + "github.com/".len()..]
} else {
trimmed
};
let path = path
.trim_start_matches('/')
.split(&['?', '#'][..])
.next()
.unwrap_or(path)
.trim_end_matches('/');
let mut parts = path.split('/');
let owner = parts.next().unwrap_or("").trim();
let repo = parts.next().unwrap_or("").trim();
if owner.is_empty() || repo.is_empty() {
bail!("unable to parse GitHub repo from: {}", input);
}
let repo = repo.strip_suffix(".git").unwrap_or(repo);
if repo.is_empty() {
bail!("unable to parse GitHub repo from: {}", input);
}
Ok(RepoRef {
owner: owner.to_string(),
repo: repo.to_string(),
})
}
pub(crate) fn normalize_root(raw: &str) -> Result<PathBuf> {
let expanded = config::expand_path(raw);
let cwd = std::env::current_dir().context("failed to resolve current directory")?;
let root = if expanded.is_absolute() {
expandedView on GitHub (pinned to a747e741ae)
Solutions
- Provide both segments: owner/repo (optionally with .git, which is stripped automatically)
- Verify the input points to a repository, not a user/org/profile page
- Add a caller-side check that the string contains exactly owner/repo before parsing
Example fix
// before
let r = parse_github_repo("https://github.com/torvalds")?;
// after
let r = parse_github_repo("https://github.com/torvalds/linux")?; Defensive patterns
Strategy: validation
Validate before calling
fn is_owner_repo_pair(input: &str) -> bool {
let t = input.trim().trim_end_matches(".git");
let t = t.rsplit_once("github.com/").map_or(t, |(_, rest)| rest);
let mut parts = t.trim_matches('/').split('/').filter(|p| !p.is_empty());
matches!((parts.next(), parts.next()), (Some(o), Some(r)) if !o.is_empty() && !r.is_empty())
} Type guard
fn has_owner_and_repo(input: &str) -> bool {
input.contains('/') && !input.trim_end_matches("/").ends_with('/')
} Try / catch
let r = parse_github_repo(input)
.map_err(|e| anyhow!("expected owner/repo, got {:?}: {e}", input))?; Prevention
- Always pass both owner and repo segments
- Verify URLs point at repositories, not user/org pages
- Check for truncation when copying repo URLs
- Normalize inputs to owner/repo shorthand in scripts
When it happens
Trigger: Calling parse_github_repo with "owner" (no slash), "owner/" (empty repo segment), "/repo" (empty owner), or a github.com URL whose path lacks owner/repo depth such as "https://github.com/owner".
Common situations: Passing just a username instead of owner/repo; truncation when copying a URL; a URL to a GitHub user profile or org page rather than a repository; config template with only the owner filled in.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse repository path from: {}
- unable to parse repository from: {}
- unable to parse repository URL: {}
- Suggested command is incomplete.
- Command '{}' is incomplete.
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/3c111459c92a226e.
Report an issue: GitHub.