{"record":{"id":"0860252c318c5cbf","repo":"warpdotdev/warp","slug":"invalid-repo-format-expected-owner-repo-o","errorCode":null,"errorMessage":"Invalid repo format: '{}'. Expected 'owner/repo' or 'https://github.com/owner/repo'","messagePattern":"Invalid repo format: '(.+?)'\\. Expected 'owner/repo' or 'https://github\\.com/owner/repo'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/src/ai/agent_sdk/agent_config.rs","lineNumber":50,"sourceCode":"        let path = spec\n            .trim_start_matches(\"https://github.com/\")\n            .trim_start_matches(\"http://github.com/\")\n            .trim_end_matches(\".git\")\n            .trim_end_matches('/');\n\n        let parts: Vec<&str> = path.split('/').collect();\n        if parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty() {\n            return Ok(GithubRepo::new(parts[0].to_string(), parts[1].to_string()));\n        }\n    }\n\n    // Try slug format: owner/repo\n    let parts: Vec<&str> = spec.split('/').collect();\n    if parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty() {\n        return Ok(GithubRepo::new(parts[0].to_string(), parts[1].to_string()));\n    }\n\n    Err(anyhow::anyhow!(\n        \"Invalid repo format: '{}'. Expected 'owner/repo' or 'https://github.com/owner/repo'\",\n        spec\n    ))\n}\n\nimpl AgentConfigRunner {\n    fn list(&self, repo: Option<String>, ctx: &mut ModelContext<Self>) -> anyhow::Result<()> {\n        // If a repo is specified, check auth first\n        if let Some(ref repo_spec) = repo {\n            let github_repo = parse_repo_spec(repo_spec)?;\n            self.auth_then_list(vec![github_repo], 1, repo, ctx);\n        } else {\n            // No repo specified - just list from environments\n            self.fetch_and_display_agents(repo, ctx);\n        }\n        Ok(())\n    }\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/app/src/ai/agent_sdk/agent_config.rs#L32-L68","documentation":"parse_repo_spec (app/src/ai/agent_sdk/agent_config.rs:27-54) accepts exactly two shapes: a URL starting with https://github.com/ or http://github.com/ (after stripping a trailing .git and /) whose remaining path has at least two non-empty segments, or a bare slug that splits on '/' into exactly two non-empty segments. The anyhow error at line 50 is the fallthrough when neither shape matches.","triggerScenarios":"Passing --repo owner/repo/ (trailing slash makes 3 segments), --repo owner (1 segment), --repo git@github.com:owner/repo.git (SSH remote: not a github.com http URL and colon does not split on '/'), or a value with surrounding quotes/whitespace beyond a simple trim.","commonSituations":"Copy-pasting the SSH remote from 'git remote -v'; URLs with trailing slashes; typos in the scheme (e.g. github.com/owner/repo without https://, which actually passes the slug branch only if exactly 2 segments).","solutions":["Pass the bare slug owner/repo with no trailing slash and no .git suffix","Or pass the full https://github.com/owner/repo URL","Copy the owner/repo slug from the GitHub repository page rather than from git remote output"],"exampleFix":"# before\n--repo git@github.com:acme/widgets.git\n# after\n--repo acme/widgets","handlingStrategy":"validation","validationCode":"fn repo_spec_is_valid(spec: &str) -> bool {\n    let s = spec.trim();\n    if s.starts_with(\"https://github.com/\") || s.starts_with(\"http://github.com/\") {\n        let path = s\n            .trim_start_matches(\"https://github.com/\")\n            .trim_start_matches(\"http://github.com/\")\n            .trim_end_matches(\".git\")\n            .trim_end_matches('/');\n        let parts: Vec<&str> = path.split('/').collect();\n        return parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty();\n    }\n    let parts: Vec<&str> = s.split('/').collect();\n    parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize repo inputs to owner/repo before passing them to CLI commands","Reject SSH remotes (git@... or ssh://) at the wrapper level and convert them to slugs"],"tags":["cli","github","parsing","validation"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}