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 GitHub relay normalizes every repository reference through the `repository()` helper, which requires exactly two path segments (`OWNER/REPO`), each non-empty, not `.` or `..`, and composed only of ASCII alphanumerics, `-`, `_`, or `.`. It is thrown whenever a repository identifier passed to `from_flags`, `expand_repository`, or `authorize` does not satisfy that shape. The value is lowercased on success so scope checks are case-insensitive.
Solutions
- Pass exactly `OWNER/REPO` (ASCII alphanumerics, `-`, `_`, `.` only), e.g. `octocat/hello-world`
- Strip scheme/host/suffix first: turn `https://github.com/org/repo.git` into `org/repo` before calling
- Check each segment against /^[A-Za-z0-9._-]+$/ and reject `.`, `..`, or empty segments yourself before calling
- For request-path errors, inspect the relayed URL's repo segment for stray characters (encodings, trailing slashes, refs) and fix the requesting client
Example fix
// before mise github-relay --scope "https://github.com/octocat/hello-world.git" // after mise github-relay --scope "octocat/hello-world"
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_repo(s: &str) -> bool {
let parts: Vec<_> = s.split('/').collect();
parts.len() == 2
&& parts.iter().all(|p| {
!p.is_empty()
&& p != "."
&& p != ".."
&& p.bytes().all(|b| b.is_ascii_alphanumeric() || b"-_.".contains(&b))
})
}
assert!(is_valid_repo("octocat/hello-world")); Type guard
fn as_owner_repo(value: &str) -> Option<(&str, &str)> {
let (owner, repo) = value.split_once('/')?;
let ok = |s: &str| {
!s.is_empty() && s != "." && s != ".."
&& s.bytes().all(|b| b.is_ascii_alphanumeric() || b"-_.".contains(&b))
};
(ok(owner) && ok(repo)).then_some((owner, repo))
} Prevention
- Always configure scopes as bare OWNER/REPO, never full URLs or SSH origins
- Normalize (strip scheme, host, .git) before validating
- Keep repo names to ASCII alphanumerics, `-`, `_`, `.`
- Validate each path segment independently to catch empty or dotted segments early
When it happens
Trigger: Passing something other than `owner/repo` to expand_repository (e.g. a bare repo name, a full URL, `owner/repo/extra`, or a value containing `:`, `@`, spaces, or shell-escaped characters); authorize() deriving `owner/repo` from a request path segment that contains a character outside the allowed set (e.g. a percent-encoded or dotted name like `../repo` or `owner/repo~`).
Common situations: Users configuring a relay scope write `github.com/org/repo` or an `https://...` URL instead of `org/repo`; typo'd extra slashes (`org//repo`); copy-pasting an SSH origin (`git@github.com:org/repo.git`); Git refs or archive paths containing characters the charset check rejects.
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
- GitHub relay is not connected
- GitHub relay permits read-only repository operations only
- invalid relay path
- invalid relay path encoding
- missing archive reference
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/ce170576425379dd.
Report an issue: GitHub.
Appendix: 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 533346cc37)