warpdotdev/warp · warning
Invalid repo format: '{}'. Expected 'owner/repo' or 'https:/
Error message
Invalid repo format: '{}'. Expected 'owner/repo' or 'https://github.com/owner/repo' What it means
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.
Source
Thrown at app/src/ai/agent_sdk/agent_config.rs:50
let path = spec
.trim_start_matches("https://github.com/")
.trim_start_matches("http://github.com/")
.trim_end_matches(".git")
.trim_end_matches('/');
let parts: Vec<&str> = path.split('/').collect();
if parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty() {
return Ok(GithubRepo::new(parts[0].to_string(), parts[1].to_string()));
}
}
// Try slug format: owner/repo
let parts: Vec<&str> = spec.split('/').collect();
if parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty() {
return Ok(GithubRepo::new(parts[0].to_string(), parts[1].to_string()));
}
Err(anyhow::anyhow!(
"Invalid repo format: '{}'. Expected 'owner/repo' or 'https://github.com/owner/repo'",
spec
))
}
impl AgentConfigRunner {
fn list(&self, repo: Option<String>, ctx: &mut ModelContext<Self>) -> anyhow::Result<()> {
// If a repo is specified, check auth first
if let Some(ref repo_spec) = repo {
let github_repo = parse_repo_spec(repo_spec)?;
self.auth_then_list(vec![github_repo], 1, repo, ctx);
} else {
// No repo specified - just list from environments
self.fetch_and_display_agents(repo, ctx);
}
Ok(())
}
View on GitHub (pinned to e72fd7aacb)
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
Example fix
# before --repo git@github.com:acme/widgets.git # after --repo acme/widgets
Defensive patterns
Strategy: validation
Validate before calling
fn repo_spec_is_valid(spec: &str) -> bool {
let s = spec.trim();
if s.starts_with("https://github.com/") || s.starts_with("http://github.com/") {
let path = s
.trim_start_matches("https://github.com/")
.trim_start_matches("http://github.com/")
.trim_end_matches(".git")
.trim_end_matches('/');
let parts: Vec<&str> = path.split('/').collect();
return parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty();
}
let parts: Vec<&str> = s.split('/').collect();
parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty()
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Invalid repo format: '{}'. Expected format: 'owner/repo'
- Exceeded maximum number of authorization attempts ({}). Plea
- GitHub authorization failed. Please try again.
- GitHub authorization expired. Please try again.
- Error polling OAuth status: {err}
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/0860252c318c5cbf.
Report an issue: GitHub.