{"record":{"id":"2f871e93e05db236","repo":"BigPizzaV3/CodexPlusPlus","slug":"http-2f871e","errorCode":null,"errorMessage":"下载 {}/{} 失败：HTTP {}{}","messagePattern":"下载 (.+?)/(.+?) 失败：HTTP (.+?)(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/skills.rs","lineNumber":968,"sourceCode":"        // 未认证请求每小时只有 60 次，四个仓库一起刷很容易撞上\n        403 | 429 => {\n            \"：GitHub API 限流。设置 GITHUB_TOKEN 环境变量可把配额从每小时 60 次提到 5000 次\"\n        }\n        404 => \"：仓库或分支不存在（私有仓库需要设置 GITHUB_TOKEN）\",\n        _ => \"\",\n    }\n}\n\npub async fn download_repo_zip(repo: &SkillRepo) -> anyhow::Result<Vec<u8>> {\n    let client = github_client()?;\n    let response = with_github_auth(client.get(repo_zip_url(repo)))\n        .header(reqwest::header::ACCEPT, \"application/zip\")\n        .send()\n        .await\n        .with_context(|| format!(\"下载 {}/{} 失败\", repo.owner, repo.name))?;\n    let status = response.status();\n    if !status.is_success() {\n        anyhow::bail!(\n            \"下载 {}/{} 失败：HTTP {}{}\",\n            repo.owner,\n            repo.name,\n            status.as_u16(),\n            github_status_hint(status.as_u16())\n        );\n    }\n    let bytes = response.bytes().await.context(\"读取仓库压缩包内容失败\")?;\n    if bytes.len() > REPO_ZIP_DOWNLOAD_LIMIT_BYTES {\n        anyhow::bail!(\"仓库压缩包太大：{} 字节\", bytes.len());\n    }\n    Ok(bytes.to_vec())\n}\n\n/// 软链优先，失败回退复制。Windows 上建目录软链要开发者模式或管理员权限，\n/// 拿不到就退化成复制——功能一样，只是更新时要重装。\nfn link_or_copy(source: &Path, link: &Path) -> anyhow::Result<()> {\n    if symlink_dir(source, link).is_ok() {","sourceCodeStart":950,"sourceCodeEnd":986,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/skills.rs#L950-L986","documentation":"download_repo_zip fetches the repo archive URL and bails on non-success status with the same HTTP-code-plus-hint pattern. Typical triggers are rate limiting (403/429) and nonexistent repo/branch (404); the hint text tells the user about GITHUB_TOKEN remedies.","triggerScenarios":"fetch 仓库 zip 下载接口返回 403 限流、404 仓库或 ref 不存在、401 token 无效、或 5xx 服务端错误。","commonSituations":"匿名下载配额用尽；仓库为私有而 token 无权限；分支名拼写错误导致 codeload 404；GitHub 下载服务临时故障。","solutions":["根据错误中的 HTTP 码定位：403 加 token/等待限流重置，404 核对 owner/name/ref，401 更换 token","确认仓库可见性，私库需配置有 repo 权限的 token","网络代理环境下检查代理是否拦截了 codeload.github.com"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let url = format!(\"https://codeload.github.com/{}/{}/zip/{}\", repo.owner, repo.name, repo.branch);\nif reqwest::Url::parse(&url).is_err() { eprintln!(\"仓库地址非法\"); return; }","typeGuard":null,"tryCatchPattern":"match download_repo_zip(&repo).await {\n    Err(e) if e.to_string().contains(\"HTTP 404\") => eprintln!(\"仓库或分支不存在，请核对 ref\"),\n    Err(e) if e.to_string().contains(\"HTTP 403\") => eprintln!(\"限流或无权限，请配置 token\"),\n    Err(e) => eprintln!(\"下载失败：{e}\"),\n    Ok(bytes) => { /* 解压 */ }\n}","preventionTips":["下载前先调文件树接口确认仓库/分支存在","私库务必配置有 repo 权限的 token","代理环境下确认 codeload.github.com 可达"],"tags":["github","http","download","zip"],"backgroundTag":"http-error-response","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}