Skip to content

[Detail Bug] CLI: Repo auto-inference fails for GitHub SSH remotes with explicit ports #272

@detail-app

Description

@detail-app

Detail Bug Report

https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_5d237de8-079c-43fb-a055-5b93a253c912

Introduced in #235 on Apr 9, 2026

Summary

  • Context: The parse_github_remote_url function extracts owner/repo from GitHub remote URLs to enable automatic repo inference for CLI commands.
  • Bug: SSH URLs with explicit port numbers (e.g., ssh://git@github.com:22/owner/repo.git) are not recognized and return None.
  • Actual vs. expected: Returns None instead of Some("owner/repo") for valid SSH URLs with port specifiers.
  • Impact: Users who configure SSH remotes with explicit ports cannot use automatic repo inference.

Code with Bug

const PREFIXES: &[&str] = &[
    "https://github.com/",
    "http://github.com/",
    "git@github.com:",
    "ssh://git@github.com/",  // <-- BUG 🔴 strict prefix rejects valid ssh://...github.com:PORT/... URLs
];

let rest = PREFIXES.iter().find_map(|p| url.strip_prefix(p))?;

Explanation

parse_github_remote_url relies on strict strip_prefix matching against a small set of hard-coded URL prefixes. For SSH scheme remotes, it only accepts ssh://git@github.com/ and therefore fails on valid Git remote URLs that include an explicit port in the authority (e.g., ssh://git@github.com:22/...). Since no prefix matches, the function returns None, which breaks repo auto-inference.

Failing Test

#[test]
fn parses_ssh_scheme_with_port() {
    // Git accepts this URL format; the CLI should too.
    assert_eq!(
        parse_github_remote_url("ssh://git@github.com:22/owner/repo.git"),
        Some("owner/repo".to_string()),
    );
}

Test output:

running 1 test
test utils::git::tests::parses_ssh_scheme_with_port ... FAILED

failures:
---- utils::git::tests::parses_ssh_scheme_with_port stdout ----
assertion `left == right` failed
  left: None
  right: Some("owner/repo")

Recommended Fix

Normalize SSH URLs with explicit ports before applying existing prefix logic (mirroring the existing HTTP-credentials normalization approach):

fn strip_ssh_port(url: &str) -> Option<String> {
    // Handle ssh://git@github.com:PORT/... -> ssh://git@github.com/...
    if let Some(rest) = url.strip_prefix("ssh://git@github.com:") {
        // Skip the port number and the following slash
        let path = rest.trim_start_matches(char::is_numeric).strip_prefix('/')?;
        return Some(format!("ssh://git@github.com/{}", path));
    }
    None
}

fn parse_github_remote_url(url: &str) -> Option<String> {
    // Normalize SSH URLs with explicit ports
    let normalized = strip_ssh_port(url);
    let url = normalized.as_deref().unwrap_or(url);

    // Continue with existing logic...
}

History

This bug was introduced in commit 575962a. The parse_github_remote_url function was created to extract owner/repo from GitHub remote URLs using simple prefix matching against known patterns. The SSH scheme prefix ssh://git@github.com/ was included but did not account for optional port numbers (e.g., :22, :443) that git accepts in this URL format. The bug went unnoticed because the test suite's 15 initial test cases did not cover SSH URLs with explicit ports, and commit fb56132 later added normalization for HTTP credentials but did not address SSH port handling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions