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() {
        expanded

View on GitHub (pinned to a747e741ae)

Solutions

  1. Provide both segments: owner/repo (optionally with .git, which is stripped automatically)
  2. Verify the input points to a repository, not a user/org/profile page
  3. 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

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

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/3c111459c92a226e. Report an issue: GitHub.