Skip to content

Enterprise GitLab remotes with non-git SSH user (e.g. gitlab@) not detected — provider stays unknown #3648

Description

@JackatDJL

Bug

When using an enterprise/self-hosted GitLab instance where the SSH remote uses a non-git SSH user (e.g., gitlab@gitlab.example.com:group/project.git), the "Create PR" workflow fails with:

Source control provider unknown failed in listChangeRequests: No unknown source control provider is registered.

Root cause

parseRemoteHost in packages/shared/src/sourceControl.ts only handled the git@ prefix when parsing SCP-like SSH remote URLs:

if (trimmed.startsWith("git@")) { ... }

Enterprise GitLab instances commonly use gitlab@ as the SSH user (this is GitLab's default). Since gitlab@... does not start with git@, the SCP-like branch was skipped. The fallback new URL(...) also fails because SCP-like syntax (user@host:path) is not a valid URL without a scheme.

As a result, parseRemoteHost returned null, detectSourceControlProviderFromRemoteUrl returned null, selectProviderContext returned null, and resolveHandle defaulted to kind: "unknown". Since no "unknown" provider is registered in the SourceControlProviderRegistry, every operation (listChangeRequests, createChangeRequest, etc.) returned the unsupported-provider error.

Reproduction

Any repo with a remote URL using a non-git SSH user triggers this:

git remote add origin gitlab@gitlab.example.com:group/project.git

Then use the "Commit + Push + PR" action in T3 Code.

Affected locations

The same startsWith("git@") assumption appears in three places:

  1. packages/shared/src/sourceControl.tsparseRemoteHost (the direct cause of this error)
  2. apps/server/src/git/GitManager.tsshouldPreferSshRemote (clone URL selection)
  3. apps/server/src/sourceControl/BitbucketApi.tsparseBitbucketRemoteUrl and shouldPreferSshRemote

Proposed fix

Replace the startsWith("git@") check with a regex that matches any SCP-like SSH syntax (user@host:path or user@host/path), covering git@, gitlab@, deploy@, and any other SSH user prefix. Extract a shared isSshRemoteUrl helper to avoid duplicating the pattern.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions