jdx/mise · error
expected a GitHub repository in OWNER/REPO form
Error message
expected a GitHub repository in OWNER/REPO form
What it means
The `repository` function in the GitHub relay normalizes and validates repository identifiers. Each OWNER and REPO segment must be non-empty, not `.` or `..`, and contain only ASCII alphanumerics, `-`, `_`, or `.`; anything else (or a missing `/` separator) yields this error. The value is lowercased on success so scope checks are case-insensitive.
Source
Thrown at src/github_relay.rs:140
};
scope
};
Ok(Some(scope))
}
fn repository(value: &str) -> Result<String> {
let parts: Vec<_> = value.split('/').collect();
if parts.len() != 2
|| parts.iter().any(|s| {
s.is_empty()
|| *s == "."
|| *s == ".."
|| !s
.bytes()
.all(|b| b.is_ascii_alphanumeric() || b"-_.".contains(&b))
})
{
bail!("expected a GitHub repository in OWNER/REPO form");
}
Ok(value.to_ascii_lowercase())
}
/// Expand only unambiguous shorthand, preserving paths and explicit transports.
pub(crate) fn expand_repository(value: &str) -> Result<String> {
if value.contains(':')
|| value.starts_with(['/', '.', '~'])
|| std::path::Path::new(value).exists()
{
return Ok(value.to_string());
}
repository(value)?;
Ok(format!(
"https://github.com/{}.git",
value.strip_suffix(".git").unwrap_or(value)
))
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Pass the repository exactly as `OWNER/REPO` with a single `/`, e.g. `octocat/hello-world`.
- Strip scheme, host, `.git` suffix where not supported, and any trailing path or ref before calling.
- Remove invalid characters (spaces, `:`, `@`, unicode) from owner and repo names.
Example fix
// before
let scope = relay::from_flags("https://github.com/octocat/hello-world")?;
// after
let scope = relay::from_flags("octocat/hello-world")?; Defensive patterns
Strategy: validation
Validate before calling
fn is_owner_repo(s: &str) -> bool {
let (o, r) = match s.split_once('/') { Some(x) => x, None => return false };
let ok = |s: &str| !s.is_empty() && s != "." && s != ".."
&& s.bytes().all(|b| b.is_ascii_alphanumeric() || b"-_..contains(&b));
ok(o) && ok(r)
}
assert!(is_owner_repo("octocat/hello-world")); Type guard
fn as_owner_repo(v: &str) -> Option<String> {
let (o, r) = v.split_once('/')?;
let ok = |s: &str| !s.is_empty() && !matches!(s, "." | "..")
&& s.bytes().all(|b| b.is_ascii_alphanumeric() || b"-_..contains(&b));
(ok(o) && ok(r)).then(|| v.to_ascii_lowercase())
} Try / catch
match relay::from_flags(input) {
Err(e) if e.to_string().contains("OWNER/REPO") => eprintln!("pass owner/repo, got {input:?}"),
Err(e) => return Err(e),
Ok(scope) => scope,
} Prevention
- Normalize GitHub URLs to owner/repo before passing (strip scheme/host and trailing paths).
- Keep a small parser helper for repo identifiers and use it everywhere.
- Never pass URLs, branch refs, or local paths where OWNER/REPO is expected.
When it happens
Trigger: Calling `repository` (via `from_flags`, `expand_repository`, or `authorize`) with a value missing the `/` separator (`myrepo`), containing invalid characters (`owner/repo!`, `owner name/repo`), empty segments (`/repo`, `owner/`), or `.`/`..` segments.
Common situations: Typing a full GitHub URL instead of OWNER/REPO; including a branch or path suffix (`owner/repo/subdir`); shell quoting or whitespace inside the value; passing a shorthand like `~` or a local path.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- invalid task action identity
- invalid action prediction adapter
- Invalid checksum: {checksum}
- additional asset '{}' is not an archive
- Invalid checksum format: {}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/ce170576425379dd.
Report an issue: GitHub.