{"record":{"id":"df9067b45b25edf3","repo":"nikivdev/code","slug":"unable-to-parse-repository-from","errorCode":null,"errorMessage":"unable to parse repository from: {}","messagePattern":"unable to parse repository from: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/repos.rs","lineNumber":1709,"sourceCode":"            bail!(\"unable to parse repository path from: {}\", input);\n        }\n        return Ok(GenericRepoRef {\n            path,\n            clone_url: trimmed.to_string(),\n        });\n    }\n\n    if let Some(at) = trimmed.find('@') {\n        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:\") {","sourceCodeStart":1691,"sourceCodeEnd":1727,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/repos.rs#L1691-L1727","documentation":"For non-URL inputs, parse_generic_repo treats the string as an scp-style or shorthand reference, splits it on '/' after trimming, and requires at least one non-empty segment. Inputs like \"git@host:\" (scp syntax with an empty path) or strings that reduce to no path segments trigger this bail.","triggerScenarios":"Calling parse_generic_repo with scp-style input missing its path, e.g. \"git@gitlab.com:\" or \"user@host:\"; looks_like_shorthand-like inputs containing '@' or no scheme but no usable path segments.","commonSituations":"Truncated paste of an scp URL where the owner/repo part was cut off; programmatic construction that appended the path only conditionally; copy of `git remote -v` line up to the colon only.","solutions":["Complete the scp-style reference with the repository path, e.g. git@gitlab.com:group/repo.git","Check the input wasn't truncated when copied or templated","Prefer a full https:// URL if the shorthand form keeps failing"],"exampleFix":"// before\nlet r = parse_generic_repo(\"git@gitlab.com:\")?;\n// after\nlet r = parse_generic_repo(\"git@gitlab.com:group/repo.git\")?;","handlingStrategy":"validation","validationCode":"fn scp_ref_has_path(input: &str) -> bool {\n    match input.trim().split_once(':') {\n        Some((_, path)) => path.trim_matches('/').split('/').any(|p| !p.is_empty()),\n        None => input.trim().split('/').any(|p| !p.is_empty()),\n    }\n}","typeGuard":"fn is_complete_scp_ref(input: &str) -> bool {\n    input.contains('@') && input.contains(':') && !input.trim_end().ends_with(':')\n}","tryCatchPattern":"let r = parse_generic_repo(input)\n    .with_context(|| format!(\"cannot interpret repo reference {:?}\", input))?;","preventionTips":["Ensure scp-style refs include the path after the colon","Avoid truncating values copied from `git remote -v` output","Prefer https:// URLs in machine-generated config","Complete templates that contain user@host: placeholders"],"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"}