{"record":{"id":"32e7daae54d90ab8","repo":"nikivdev/code","slug":"unable-to-parse-repository-url","errorCode":null,"errorMessage":"unable to parse repository URL: {}","messagePattern":"unable to parse repository URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/repos.rs","lineNumber":1718,"sourceCode":"        if let Some(colon) = trimmed[at + 1..].find(':') {\n            let rest = &trimmed[at + 1 + colon + 1..];\n            let path = rest\n                .trim_matches('/')\n                .split('/')\n                .filter(|p| !p.is_empty())\n                .map(|p| p.trim_end_matches(\".git\").to_string())\n                .collect::<Vec<_>>();\n            if path.is_empty() {\n                bail!(\"unable to parse repository from: {}\", input);\n            }\n            return Ok(GenericRepoRef {\n                path,\n                clone_url: trimmed.to_string(),\n            });\n        }\n    }\n\n    bail!(\"unable to parse repository URL: {}\", input)\n}\n\npub(crate) fn parse_github_repo(input: &str) -> Result<RepoRef> {\n    let trimmed = input.trim();\n    if trimmed.is_empty() {\n        bail!(\"missing repository URL\");\n    }\n\n    let path = if let Some(rest) = trimmed.strip_prefix(\"git@github.com:\") {\n        rest\n    } else if let Some(idx) = trimmed.find(\"github.com/\") {\n        &trimmed[idx + \"github.com/\".len()..]\n    } else {\n        trimmed\n    };\n\n    let path = path\n        .trim_start_matches('/')","sourceCodeStart":1700,"sourceCodeEnd":1736,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/repos.rs#L1700-L1736","documentation":"This is parse_generic_repo's final fallback: if the input is non-empty, not parseable as a URL with a usable path, and not recognized as a shorthand/scp-style reference, the function gives up and bails with the raw input embedded in the message. It signals the string is not in any repository-reference format the library understands.","triggerScenarios":"Passing malformed input to parse_generic_repo such as \"not a url!!\", \"://bad\", \"owner only\" (no '/', '@', or scheme), or a reference format the parser doesn't recognize.","commonSituations":"Typos in scheme (htps://...); free-form text pasted from docs; Windows-style paths or local file paths the parser doesn't treat as URLs; a config value with stray characters.","solutions":["Use a full repository URL (https://host/owner/repo.git) or an scp-style ref (git@host:owner/repo.git) or a recognized shorthand (owner/repo)","Check for typos in the URL scheme and stray whitespace/special characters","If it's a local path, confirm the library supports local paths or convert it to a file:// URL"],"exampleFix":"// before\nlet r = parse_generic_repo(\"my repo thing\")?;\n// after\nlet r = parse_generic_repo(\"https://gitlab.com/group/repo.git\")?;","handlingStrategy":"validation","validationCode":"fn looks_like_repo_ref(input: &str) -> bool {\n    let t = input.trim();\n    t.contains(\"://\") || t.contains('@') || t.split('/').filter(|p| !p.is_empty()).count() >= 2\n}","typeGuard":"fn is_parseable_repo_ref(input: &str) -> bool {\n    let t = input.trim();\n    !t.is_empty() && (t.starts_with(\"http://\") || t.starts_with(\"https://\") || t.contains('@') || t.split('/').count() >= 2)\n}","tryCatchPattern":"let r = parse_generic_repo(input).unwrap_or_else(|e| {\n    eprintln!(\"{e}; expected a URL, scp-style ref, or owner/repo shorthand\");\n    std::process::exit(2);\n});","preventionTips":["Use one of the three accepted formats: URL, scp ref, or shorthand","Fix typos in URL schemes (htps:// -> https://)","Don't paste free-form documentation text as a repo reference","Convert local paths to file:// URLs if supported"],"tags":["input-validation","url-parsing","git"],"backgroundTag":"invalid-repository-url","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}