{"record":{"id":"49580c52e6132ba2","repo":"jdx/mise","slug":"invalid-http-setup-repository-url-use-a-git-crede","errorCode":null,"errorMessage":"invalid HTTP setup repository URL; use a Git credential helper for authentication","messagePattern":"invalid HTTP setup repository URL; use a Git credential helper for authentication","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/network.rs","lineNumber":34,"sourceCode":"#[error(\"{0}\")]\npub(crate) struct NetworkError(pub String);\n\n/// Authentication belongs in a credential helper or SSH agent, never in\n/// persisted connection URLs or the errors recorded in history health.\npub(crate) fn validate_url(value: &str) -> Result<()> {\n    if value.trim().is_empty() || value.trim_start().starts_with('-') {\n        bail!(\"setup repository URL must be nonempty and must not start with '-'\");\n    }\n    let http_like = value\n        .trim_start()\n        .get(..5)\n        .is_some_and(|prefix| prefix.eq_ignore_ascii_case(\"http:\"))\n        || value\n            .trim_start()\n            .get(..6)\n            .is_some_and(|prefix| prefix.eq_ignore_ascii_case(\"https:\"));\n    if http_like && url::Url::parse(value).is_err() {\n        bail!(\"invalid HTTP setup repository URL; use a Git credential helper for authentication\");\n    }\n    if let Ok(url) = url::Url::parse(value) {\n        let http = matches!(url.scheme(), \"http\" | \"https\");\n        if url.password().is_some()\n            || (http\n                && (!url.username().is_empty()\n                    || url.query().is_some()\n                    || url.fragment().is_some()))\n        {\n            bail!(\n                \"setup repository URLs must not contain credentials, query parameters, or fragments; use a Git credential helper or SSH agent\"\n            );\n        }\n    }\n    Ok(())\n}\n\n#[cfg(test)]","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/network.rs#L16-L52","documentation":"`validate_url` in src/system/history/sync/network.rs requires that a URL which looks like HTTP/HTTPS actually parse as a valid URL. If the prefix is `http:`/`https:` (case-insensitive) but `url::Url::parse` fails, this error is thrown. The message deliberately avoids echoing the URL back so that any embedded credentials (e.g. `https://token@host/...`) are never leaked into errors recorded in history health; it also instructs the user to use a Git credential helper for authentication instead.","triggerScenarios":"Calling any `Remote` network method with an HTTP(S)-prefixed string that is not a parseable URL — e.g. `\"https://secret@example.com:bad/repo\"` (invalid port), `\"HTTP://secret@[broken/repo\"` (malformed host), a truncated URL with unbalanced brackets, or spaces/illegal characters in an https URL.","commonSituations":"Pasting a URL with an embedded access token or password into the remote field; hand-editing the URL and corrupting the host or port; missing scheme characters (e.g. `https:/host` with one slash); shell/quoting mangling of the URL before it reaches mise; uppercase-scheme URLs with bad hosts.","solutions":["Fix the URL so it is a valid absolute HTTP(S) URL (balanced brackets, valid host and port, e.g. `https://github.com/user/dotfiles.git`).","Remove any embedded username/password/token from the URL and configure a Git credential helper (`git config --global credential.helper`) or SSH remote instead — credentials in URLs are also rejected outright.","Copy the URL fresh from the provider (GitHub/GitLab clone button) to avoid transcription errors; test it with `git ls-remote <url>`."],"exampleFix":"// before (config)\nhistory.remote = \"https://ghp_secret@github.com:bad/repo\"\n\n// after\nhistory.remote = \"https://github.com/user/dotfiles.git\"\n// plus: git config --global credential.helper store","handlingStrategy":"validation","validationCode":"fn is_valid_http_url(v: &str) -> bool {\n    let t = v.trim_start();\n    let http_like = t.get(..5).map_or(false, |p| p.eq_ignore_ascii_case(\"http:\"))\n        || t.get(..6).map_or(false, |p| p.eq_ignore_ascii_case(\"https:\"));\n    !http_like || url::Url::parse(v).is_ok()\n}","typeGuard":null,"tryCatchPattern":"// Rust\nmatch validate_url(url) {\n    Ok(()) => remote.fetch(\"main\")?,\n    Err(e) if e.to_string().contains(\"credential helper\") => {\n        eprintln!(\"URL is malformed or embeds credentials; use `git config credential.helper` instead\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never embed usernames, passwords, or tokens in remote URLs — configure a Git credential helper or use SSH remotes","Copy HTTPS URLs directly from the provider's clone button to avoid transcription errors","Test the URL with `git ls-remote <url>` before saving it to settings","Watch for shell quoting or templating that mangles brackets, ports, or slashes in URLs"],"tags":["git","url","validation","security","credentials"],"backgroundTag":"invalid-url","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"}