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

  1. Pass the bare slug owner/repo with no trailing slash and no .git suffix
  2. Or pass the full https://github.com/owner/repo URL
  3. 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

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


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/0860252c318c5cbf. Report an issue: GitHub.