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
- Provide the URI in one of the supported forms: 'user/repo', 'domain/user/repo', a full https URL, or an SSH URI
- If you only know the repo name, prefix the GitHub user: 'denisidoro/navi' instead of 'navi'
- Validate the URI shape before calling (contains '/' or '://' or '@') to avoid the panic
- 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
- Always pass user/repo or a full URL/SSH URI, never a bare repo name
- Validate the URI shape before invoking meta
- Trim shell input and guard against empty variables (${VAR:?msg})
- Prefer shallow_clone with a validated URI
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.