{"record":{"id":"80bf56f97be89a03","repo":"jdx/mise","slug":"repository-origin-must-not-contain-credentials-qu","errorCode":null,"errorMessage":"repository origin must not contain credentials, query parameters, or fragments","messagePattern":"repository origin must not contain credentials, query parameters, or fragments","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote_repository.rs","lineNumber":71,"sourceCode":"        && origin.split_once(\"::\").is_some_and(|(prefix, _)| {\n            !prefix.is_empty() && !prefix.contains(['/', '\\\\', '[', ']', '@', ':'])\n        })\n    {\n        bail!(\"Git remote helpers are not supported for remote onboarding\");\n    }\n    if !explicit_local && origin.contains(\"://\") {\n        let url = url::Url::parse(origin).wrap_err(\"invalid repository URL\")?;\n        if !matches!(url.scheme(), \"https\" | \"ssh\" | \"file\") {\n            bail!(\"remote bootstrap requires HTTPS, SSH, or a local path\");\n        }\n    }\n    if let Ok(url) = url::Url::parse(origin)\n        && (url.password().is_some()\n            || (url.scheme() != \"ssh\" && !url.username().is_empty())\n            || url.query().is_some()\n            || url.fragment().is_some())\n    {\n        bail!(\"repository origin must not contain credentials, query parameters, or fragments\");\n    }\n    Ok(())\n}\n\nimpl Source {\n    pub(crate) async fn fetch(origin: String) -> Result<Self> {\n        validate_origin(&origin)?;\n        let directory = tempfile::tempdir()?;\n        let repo = directory.path().join(\"repo\");\n        let mut command = Command::new(\"git\");\n        crate::git::sanitize_git_command(&mut command);\n        // No checkout: source templates and hooks are never evaluated locally.\n        command\n            .env(\"GIT_ALLOW_PROTOCOL\", \"https:ssh:file\")\n            .args([\"-c\", &crate::git::github_credential_config(\"github.com\")])\n            .args([\n                \"-c\",\n                &crate::git::github_credential_config(\"github.com:443\"),","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/remote_repository.rs#L53-L89","documentation":"mise rejects repository origins that embed credentials (password, or non-ssh username), query strings, or URL fragments. Onboarding transfers the repo via a bundle and later re-sets the origin; embedded secrets or extra URL parts break cloning and risk credential leakage.","triggerScenarios":"Calling Source::fetch or install_at with an origin such as https://user:token@github.com/owner/repo?ref=main#frag.","commonSituations":"Pasting a URL copied from a browser address bar while logged in (contains ?tab=... or #...), or hardcoding a PAT into the remote URL.","solutions":["Remove the username/password from the URL and rely on the local git credential helper","Strip query parameters and fragments from the origin","For private repos over SSH, use an ssh:// URL with no inline credentials"],"exampleFix":"// before\nlet origin = \"https://user:ghp_xxx@github.com/owner/repo.git?tab=readme\";\n// after\nlet origin = \"https://github.com/owner/repo.git\";","handlingStrategy":"validation","validationCode":"fn origin_clean(origin: &str) -> bool {\n    origin.contains(\"@\") == false || origin.starts_with(\"ssh://\") || !origin.contains(\"://\")\n        && !origin.contains('?') && !origin.contains('#')\n}","typeGuard":"fn is_credential_free_url(origin: &str) -> bool {\n    url::Url::parse(origin).map(|u| {\n        u.password().is_none()\n            && (u.scheme() == \"ssh\" || u.username().is_empty())\n            && u.query().is_none()\n            && u.fragment().is_none()\n    }).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Never embed tokens or passwords in remote URLs; rely on credential helpers","Copy clone URLs from the repo's Clone button, not the browser address bar","Sanitize URLs by stripping ?query and #fragment before passing them"],"tags":["git","security","url"],"backgroundTag":"invalid-url","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}