denisidoro/navi · error

Invalid link

Error message

Invalid link

What it means

navi's `common::git::meta` parses a git URI into (url, user, repo). If the input contains no '://' scheme, no '@' (SSH style), and no '/' separator at all (so it can't be split into domain/route or user/repo), the parser has no way to interpret it and panics with "Invalid link". It's a hard panic, not a Result, because the function signature returns a tuple.

Source

Thrown at src/common/git.rs:32

pub fn meta(uri: &str) -> (String, String, String) {
    let actual_uri = if uri.contains("://") || uri.contains('@') {
        uri.to_string()
    } else if let Some((domain, route)) = uri.split_once('/') {
        if domain.contains(".") {
            format!("https://{domain}/{route}")
        } else {
            // Users can pass name starting wirh a slash
            let first_char = uri.chars().next();

            if first_char == Some('/') {
                format!("https://github.com{uri}")
            } else {
                format!("https://github.com/{uri}")
            }
        }
    } else {
        panic!("Invalid link")
    };

    let uri_to_split = actual_uri.replace(':', "/");
    let parts: Vec<&str> = uri_to_split.split('/').collect();
    let user = parts[parts.len() - 2];
    let repo = parts[parts.len() - 1].replace(".git", "");

    (actual_uri, user.to_string(), repo)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_meta_github_https() {
        let (actual_uri, user, repo) = meta("https://github.com/denisidoro/navi");
        assert_eq!(actual_uri, "https://github.com/denisidoro/navi".to_string());

View on GitHub (pinned to f7330b9ad5)

Solutions

  1. Provide the URI in one of the supported forms: 'user/repo', 'domain/user/repo', a full https URL, or an SSH URI
  2. If you only know the repo name, prefix the GitHub user: 'denisidoro/navi' instead of 'navi'
  3. Validate the URI shape before calling (contains '/' or '://' or '@') to avoid the panic
  4. Upstream: convert the panic to a Result error for graceful handling

Example fix

// before
let (_, user, repo) = navi::common::git::meta("navi");
// after
let input = "navi";
assert!(input.contains('/') || input.contains("://") || input.contains('@'), "Invalid link: pass user/repo");
let (_, user, repo) = navi::common::git::meta("denisidoro/navi");
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_git_uri(uri: &str) -> bool {
    uri.contains("://") || uri.contains('@') || uri.contains('/')
}
if !is_valid_git_uri(input) {
    eprintln!("Invalid link: expected user/repo, URL, or SSH URI");
    std::process::exit(1);
}
let meta = navi::common::git::meta(input);

Type guard

fn looks_like_git_link(s: &str) -> bool {
    !s.is_empty() && (s.contains("://") || s.contains('@') || s.split_once('/').is_some())
}

Try / catch

// meta panics rather than returning Result; isolate it
let result = std::panic::catch_unwind(|| navi::common::git::meta(uri));
match result {
    Ok((url, user, repo)) => println!("{} {} {}", url, user, repo),
    Err(_) => eprintln!("invalid link: {}", uri),
}

Prevention

When it happens

Trigger: Calling `git::meta(uri)` with a bare word that has no slash and no scheme/SSH marker, e.g. `meta("navi")` or `meta("")`. Any URI accepted must look like 'user/repo', 'github.com/user/repo', '/user/repo', 'https://host/user/repo', or 'git@host:user/repo.git'.

Common situations: Users typing just a repo name into `navi repo <name>` (intending a single-word shortcut), typos dropping the 'user/' prefix, shell variable interpolation yielding an empty string, or passing a local filesystem path without a slash.

Related errors


AI-assisted analysis of denisidoro/navi@f7330b9ad5 (2026-09-03). Data as JSON: /api/errors/84a83f5645df8d70. Report an issue: GitHub.