{"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/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/github_relay.rs#L239-L275","documentation":"The GitHub relay's authorize step only accepts archive requests in a recognized format (tarball/zipball suffix). After stripping the suffix it requires a non-empty reference (tag, branch or commit SHA) to build the api.github.com archive URL. If the reference is empty — e.g. the path was just \".zip\" or a bare prefix — it refuses with \"missing archive reference\" rather than issuing a meaningless upstream request.","triggerScenarios":"Calling the relay's authorize/operation path (directly or via forward / web_archives_use_scoped_api_downloads) with an archive reference that strips to empty: a path ending in \".tar.gz\" or \".zip\" with no repo ref before the suffix (e.g. /repo/archive/.zip).","commonSituations":"Templates or scripts interpolating a version variable that resolved to an empty string; misconfigured download URLs where the ref segment was accidentally dropped; programmatic URL builders emitting a trailing suffix only.","solutions":["Supply a concrete ref (tag, branch, or commit SHA) before the archive suffix, e.g. /archive/refs/tags/v1.2.3.tar.gz.","Fix the source of the empty value — check the version/ref variable being interpolated into the archive URL.","Fall back to a plain git clone or a direct codeload URL if you need an unnamed default-branch archive, which this authorize path does not accept."],"exampleFix":"// before\nlet url = format!(\"https://github.com/foo/bar/archive/{version}.tar.gz\"); // version == \"\"\n// after\nlet version = version.non_empty().ok_or_else(|| eyre::eyre!(\"version required for archive download\"))?;\nlet url = format!(\"https://github.com/foo/bar/archive/{version}.tar.gz\");","handlingStrategy":"validation","validationCode":"fn archive_ref(url_path: &str) -> Option<&str> {\n    for suffix in [\".tar.gz\", \".zip\"] {\n        if let Some(r) = url_path.strip_suffix(suffix) {\n            if !r.is_empty() {\n                return Some(r);\n            }\n        }\n    }\n    None\n}\n// call before issuing the request; bail early if None","typeGuard":"fn has_archive_ref(reference: &str) -> bool {\n    !reference.is_empty()\n}","tryCatchPattern":null,"preventionTips":["Never build archive URLs from variables that may be empty; assert the ref is non-empty first.","Use concrete tags or SHAs in templates rather than optional/unset version fields.","Validate URL shape in one helper so the empty-ref case is caught before any request."],"tags":["validation","archive","github","missing-argument"],"backgroundTag":"empty-required-field","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}