jdx/mise · error
unsupported archive format
Error message
unsupported archive format
What it means
For `web/OWNER/REPO/archive/...` requests, the relay rewrites the download to the corresponding GitHub API `tarball`/`zipball` endpoint. The final path segment must end in `.tar.gz` (mapped to `tarball`) or `.zip` (mapped to `zipball`); any other archive suffix is rejected. This ensures the relay only proxies the two archive formats GitHub's API provides.
Solutions
- Use `.tar.gz` for a tarball or `.zip` for a zipball at the end of the archive path
- Replace `.tgz` with `.tar.gz` (GitHub web archive URLs use `.tar.gz`, not `.tgz`)
- If you need another format, download the `.tar.gz`/`.zip` and convert locally
Example fix
// before GET /web/org/repo/archive/refs/tags/v1.0.tgz // after GET /web/org/repo/archive/refs/tags/v1.0.tar.gz
Defensive patterns
Strategy: validation
Validate before calling
fn archive_kind(url_path: &str) -> Option<&'static str> {
if url_path.ends_with(".tar.gz") { Some("tarball") }
else if url_path.ends_with(".zip") { Some("zipball") }
else { None }
}
assert_eq!(archive_kind("/web/o/r/archive/v1.0.tar.gz"), Some("tarball")); Try / catch
match authorize(&scope, method, path, query) {
Err(e) if e.to_string().contains("unsupported archive format") => {
eprintln!("use .tar.gz or .zip suffix for archive downloads");
}
Ok(t) => forward(t),
Err(e) => return Err(e),
} Prevention
- Use exactly .tar.gz (not .tgz/.tar.bz2) or .zip in archive URLs
- Match the extension to the format you actually want to download
- Convert other formats locally after downloading a supported archive
- Template URLs with the correct fixed extension rather than deriving it from input
When it happens
Trigger: A client requests an archive URL ending in something other than `.tar.gz` or `.zip`, e.g. `/web/org/repo/archive/refs/tags/v1.0.tar.bz2`, `.tgz`, `.7z`, or no extension at all (`/archive/refs/tags/v1.0`).
Common situations: Tools defaulting to GitHub's codeload `.tgz` naming; users hand-writing archive URLs with `.tar` or `.zip.gz`; templated URLs that append the wrong extension for the chosen format.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- missing archive reference
- GitHub relay permits read-only repository operations only
- repository is outside the approved relay scope
- unsupported GitHub operation
- unsupported query parameter
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/6c3394e7c4c9a3ae.
Report an issue: GitHub.
Appendix: source
Thrown at src/github_relay.rs:254
}
}
let host = if p[0] == "api" {
"api.github.com"
} else {
"github.com"
};
let suffix = path.split_once('/').expect("validated path").1;
let mut url = format!("https://{host}/{suffix}");
let archive_repo = match p.as_slice() {
["api", "repos", _, _, "tarball" | "zipball", ..] => Some(name.clone()),
["web", _, _, "archive", rest @ ..] => {
let reference = rest.join("/");
let (kind, reference) = if let Some(reference) = reference.strip_suffix(".tar.gz") {
("tarball", reference)
} else if let Some(reference) = reference.strip_suffix(".zip") {
("zipball", reference)
} else {
bail!("unsupported archive format");
};
if reference.is_empty() {
bail!("missing archive reference");
}
// The API supplies short-lived private archive links; credentials
// remain at the API origin and are never attached to that redirect.
url = format!("https://api.github.com/repos/{name}/{kind}/{reference}");
Some(name)
}
_ => None,
};
if let Some(query) = query {
url.push('?');
url.push_str(query);
}
Ok(Target {
url,
git,View on GitHub (pinned to 533346cc37)