{"id":"aeeecb98c8f1113e","repo":"rust-lang/cargo","slug":"too-many-segments-on-url","errorCode":null,"errorMessage":"too many segments on URL","messagePattern":"too many segments on URL","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"src/sources/git/utils.rs","lineNumber":1658,"sourceCode":"                debug!(\"can't use github fast path with `rev = \\\"{}\\\"`\", rev);\n                return Ok(FastPathRev::Indeterminate);\n            }\n        }\n    };\n\n    // This expects GitHub urls in the form `github.com/user/repo` and nothing\n    // else\n    let mut pieces = url\n        .path_segments()\n        .ok_or_else(|| anyhow!(\"no path segments on url\"))?;\n    let username = pieces\n        .next()\n        .ok_or_else(|| anyhow!(\"couldn't find username\"))?;\n    let repository = pieces\n        .next()\n        .ok_or_else(|| anyhow!(\"couldn't find repository name\"))?;\n    if pieces.next().is_some() {\n        anyhow::bail!(\"too many segments on URL\");\n    }\n\n    // Trim off the `.git` from the repository, if present, since that's\n    // optional for GitHub and won't work when we try to use the API as well.\n    let repository = repository.strip_suffix(\".git\").unwrap_or(repository);\n\n    let url = format!(\n        \"https://api.github.com/repos/{}/{}/commits/{}\",\n        username, repository, github_branch_name,\n    );\n    debug!(\"attempting GitHub fast path for {}\", url);\n    let mut request =\n        Request::get(url).header(http::header::ACCEPT, \"application/vnd.github.3.sha\");\n    if let Some(local_object) = local_object {\n        request = request.header(http::header::IF_NONE_MATCH, &format!(\"\\\"{local_object}\\\"\"));\n    }\n    let response = gctx\n        .http_async()?","sourceCodeStart":1640,"sourceCodeEnd":1676,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/sources/git/utils.rs#L1640-L1676","documentation":"In `github_fast_path`, a third path segment exists after `user/repo` (e.g. `github.com/user/repo/extra`). Cargo expects exactly two segments for the GitHub API fast path, so it bails. Unlike 162–164 (which use `ok_or_else`/`?`), this one uses `anyhow::bail!`, but it is still caught by the caller at src/sources/git/utils.rs:1039 and swallowed into a `debug!` log + fallback fetch.","triggerScenarios":"A git dependency URL with a trailing path component beyond `user/repo`, such as `https://github.com/org/repo/tree/main` or a URL with a trailing `/sub` path. Reached inside the GitHub fast path only.","commonSituations":"Copy-pasting a browser URL (with `/tree/<branch>` or `/blob/...`) into `Cargo.toml` as the `git` field; trailing-slash or extra path from a mirror config. Usually only visible in debug logs because the caller falls back to a full fetch.","solutions":["Trim the URL to the bare repository: `https://github.com/<user>/<repo>`, and express branch/tag via the `branch`/`tag`/`rev` keys instead.","If seen only in debug logs, it's harmless — Cargo's normal fetch handles it."],"exampleFix":"# before\nfoo = { git = \"https://github.com/org/repo/tree/v1\" }\n\n# after\nfoo = { git = \"https://github.com/org/repo\", tag = \"v1\" }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Same pattern: catch Err, log at debug, proceed to a full fetch.\nmatch github_fast_path(repo, url, reference, gctx) {\n    Ok(r) => r,\n    Err(e) => { debug!(\"failed to check github {:?}\", e); /* full fetch */ }\n}","preventionTips":["Use bare repo URLs and express branches/tags via the `branch`/`tag`/`rev` keys, not extra path segments.","Never propagate errors from the GitHub fast path."],"tags":["cargo","git","github-fast-path","url","internal"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}