{"record":{"id":"63d2d3ae8462e0a9","repo":"jdx/mise","slug":"missing-archive-reference","errorCode":null,"errorMessage":"missing archive reference","messagePattern":"missing archive reference","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/github_relay.rs","lineNumber":257,"sourceCode":"        \"api.github.com\"\n    } else {\n        \"github.com\"\n    };\n    let suffix = path.split_once('/').expect(\"validated path\").1;\n    let mut url = format!(\"https://{host}/{suffix}\");\n    let archive_repo = match p.as_slice() {\n        [\"api\", \"repos\", _, _, \"tarball\" | \"zipball\", ..] => Some(name.clone()),\n        [\"web\", _, _, \"archive\", rest @ ..] => {\n            let reference = rest.join(\"/\");\n            let (kind, reference) = if let Some(reference) = reference.strip_suffix(\".tar.gz\") {\n                (\"tarball\", reference)\n            } else if let Some(reference) = reference.strip_suffix(\".zip\") {\n                (\"zipball\", reference)\n            } else {\n                bail!(\"unsupported archive format\");\n            };\n            if reference.is_empty() {\n                bail!(\"missing archive reference\");\n            }\n            // The API supplies short-lived private archive links; credentials\n            // remain at the API origin and are never attached to that redirect.\n            url = format!(\"https://api.github.com/repos/{name}/{kind}/{reference}\");\n            Some(name)\n        }\n        _ => None,\n    };\n    if let Some(query) = query {\n        url.push('?');\n        url.push_str(query);\n    }\n    Ok(Target {\n        url,\n        git,\n        archive_repo,\n    })\n}","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/github_relay.rs#L239-L275","documentation":"When a `web/OWNER/REPO/archive/...` URL ends in `.tar.gz` or `.zip`, the remaining text before that suffix is the git reference to archive (e.g. `refs/tags/v1.0` or `main`). If that reference is empty — meaning the path ends right at the suffix with nothing identifying what to archive — the relay rejects the request since there is no meaningful upstream URL to build.","triggerScenarios":"Requests like `/web/org/repo/archive/.tar.gz` or `/web/org/repo/archive/.zip` where the reference portion before the extension is empty (a tag/ref name consisting solely of the stripped extension, or a path where the ref got dropped).","commonSituations":"URL templates where a `${version}`/`${ref}` variable expanded to empty because the version was not provided; a build script stripping the ref accidentally (e.g. an over-eager suffix trim leaving nothing); copy-paste of an archive URL that lost its ref segment.","solutions":["Include the git reference before the extension, e.g. `/web/org/repo/archive/refs/tags/v1.0.tar.gz` or `/web/org/repo/archive/main.zip`","Fix the templating/variable so the version or ref is actually substituted into the URL","Verify the path was not truncated — the full `refs/tags/<tag>` (or branch name) must be present"],"exampleFix":"// before\nGET /web/org/repo/archive/refs/tags/.tar.gz\n// after\nGET /web/org/repo/archive/refs/tags/v1.0.tar.gz","handlingStrategy":"validation","validationCode":"fn archive_ref_is_present(path: &str) -> bool {\n    for ext in [\".tar.gz\", \".zip\"] {\n        if let Some(rest) = path.strip_suffix(ext) {\n            return rest.rsplit('/').next().map_or(false, |s| !s.is_empty());\n        }\n    }\n    false\n}\nassert!(archive_ref_is_present(\"/web/o/r/archive/refs/tags/v1.0.tar.gz\"));","typeGuard":null,"tryCatchPattern":"match authorize(&scope, method, path, query) {\n    Err(e) if e.to_string().contains(\"missing archive reference\") => {\n        eprintln!(\"archive URL is missing the git ref before the extension\");\n    }\n    Ok(t) => forward(t),\n    Err(e) => return Err(e),\n}","preventionTips":["Always interpolate the version/ref into archive URL templates and fail loudly if the variable is empty","Validate templated URLs render with a non-empty ref before issuing requests","Prefer explicit refs/tags/<tag> or branch-name paths over hand-trimmed URLs","Watch for trim/suffix-strip logic that can remove the ref along with the extension"],"tags":["github","relay","archive","missing-reference","download"],"backgroundTag":"missing-required-argument","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}