Skip to content

[Bug]: Partial-clone remote annotations break repository detection and hide linked PRs #12764

Description

@vedprakash2302

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Add a partial-clone repository whose git remote -v output includes a filter annotation after the fetch direction. The affected checkout has remote.origin.promisor=true and remote.origin.partialclonefilter=blob:none.
  2. Create a PR and link it to a thread in T3 Code.
  3. Open the Pull Requests view. The thread retains its PR link, but the PR is missing from the view and its saved status snapshot remains empty.

Actual remote output, with the private repository replaced by an example:

origin https://example.visualstudio.com/DefaultCollection/Project/_git/repo (fetch) [blob:none]
origin https://example.visualstudio.com/DefaultCollection/Project/_git/repo (push)

The parser failure can be reproduced without credentials or a private repository:

const parse = /^(\S+)\s+(\S+)\s+\((fetch|push)\)$/;
const remote = "origin https://example.visualstudio.com/DefaultCollection/Project/_git/repo";
console.log(parse.test(`${remote} (fetch)`)); // true
console.log(parse.test(`${remote} (fetch) [blob:none]`)); // false

Expected behavior

T3 recognizes the fetch remote and its source-control provider even when Git appends a partial-clone filter annotation. PR listing and linked-PR synchronization work for this checkout.

Actual behavior

The parser discards the fetch line because it anchors the end of the line immediately after (fetch) or (push). The repository identity resolver then has no fetch remote from which to build an identity. PR listing skips projects without that identity.

The saved thread link exists independently of repository discovery, which explains why the PR number can appear beside the thread while the PR view cannot list it.

Verified on the affected environment:

  • Azure CLI is signed in as the PR author.
  • az repos pr show --detect true --id <id> succeeds.
  • az repos pr list --detect true --repository <repo> --status active --creator <author> returns the PR.
  • The thread-to-PR record exists, but snapshot_json is null.
  • T3 logs report an unknown source-control provider and skip linked-PR synchronization.

The same end-anchored regex appears in three parsers at commit c14f6015bfe479d313355cb234af1a5c16dbb15f:

The repository identity parser is also present in current upstream source at the time of filing. The rejection happens before host-specific PR calls, so the parser defect is not specific to Azure DevOps. End-to-end symptoms were observed with Azure DevOps.

Impact

Major degradation or frequent failure. PR integration fails for the affected partial-clone checkout while ordinary Git and Azure CLI access still work.

Version or commit

Desktop version reported in logs: 0.0.43-nightly.20260920.2005.

Source inspected: c14f6015bfe479d313355cb234af1a5c16dbb15f.

Environment

Windows desktop app connected to its Linux/WSL server runtime. Git 2.52.0.vfs.0.5. Azure DevOps repository with a blob:none partial-clone filter.

Logs or stack traces

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

pull request sync skipped

Workaround

Use the provider website or Azure CLI to inspect the PR. No repository configuration changes were made during diagnosis.

Related issues

#7647 concerns a different Azure DevOps repository-name mismatch when opening PR details from chat. This report concerns fetch-remote parsing and repository discovery before PR listing.

Investigation

Investigated and filed with GPT-6 Astra through OpenCode in T3 Code. Private repository names, PR identifiers, account details, and local paths have been omitted.

Activity

  1. juliusmarminge commented on Sep 20, 2026

    @juliusmarminge
    Member

    Thanks for the unusually complete report — this is a real parser bug, still present on current main, and it is not Azure DevOps-specific.

    What we confirmed

    Git really does append a filter annotation on promisor remotes. On this machine (Git 2.43.0):

    origin  https://example.visualstudio.com/DefaultCollection/Project/_git/repo (fetch) [blob:none]
    origin  https://example.visualstudio.com/DefaultCollection/Project/_git/repo (push)
    

    The same end-anchored regex still appears in three places:

    A fetch line that ends with [blob:none] is discarded. The push line still parses, but listing only keeps remotes that have a fetch URL, so the remote disappears entirely.

    That matches the two symptoms you saw:

    1. PR view empty, thread pill still present. PullRequestService skips any project whose repositoryIdentity is missing. The thread→PR row is stored separately, so the number can still show beside the thread while snapshot_json stays null.
    2. Source control provider unknown failed in listChangeRequests / pull request sync skipped. SourceControlProviderRegistry detects the host from listRemotes. With no fetch URL it falls through to the unregistered unknown stub — the exact error in your logs — and PullRequestSyncReactor then skips the snapshot write. That happens before any az repos call, which is why Azure CLI succeeding does not help.

    Existing tests only feed unannotated origin … (fetch) lines, so this never failed CI.

    Related, not duplicates

    Existing PR is incomplete

    #7499 already proposes the identity-resolver change ((?:\s+\[[^\]]+\])* after (fetch|push)) plus a promisor-config test. It does not update the two GitVcsDriver* copies. Landing it as-is would restore repositoryIdentity (and therefore PR-list grouping) but provider detection via listRemotes — the path behind your log line — would still fail.

    Next step

    Extend #7499 (or a follow-up) so all three parsers share one suffix-tolerant helper. Prefer a synthetic-stdout unit case for … (fetch) [blob:none]; a live git config remotes.origin.partialclonefilter test can pass on a Git that never prints the annotation. No repository-side workaround is required once those parsers accept Git’s optional filter suffix.

    Accepting as a bug.

  2. added
    bugSomething is broken or behaving incorrectly.
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    on Sep 20, 2026
  3. cestercian commented on Sep 21, 2026

    @cestercian
    Contributor

    stepping back — #12776 already covers this

  4. vedprakash2302 commented on Sep 21, 2026

    @vedprakash2302
    ContributorAuthor

    Confirmed another user-visible consequence of this parser bug: the same repository appears as separate sidebar projects across two environments.

    The two checkouts have identical origin URLs. One is a partial clone whose fetch line ends in (fetch) [blob:none]; the other has a plain (fetch) line. Inspection of the running WSL server binary confirmed that its repository-identity parser still uses the end-anchored regex described above.

    The partial-clone checkout therefore loses its repository identity. The shared client grouping logic in packages/client-runtime/src/state/projectGrouping.ts uses repositoryIdentity.canonicalKey to merge repositories across environments, but falls back to an environment-and-workspace-path key when the identity is missing. That fallback keeps the two checkouts separate. Another repository with ordinary remote output groups correctly in the same client.

    This is another consequence of the existing bug, rather than a separate grouping defect. Verification of the parser fix should include a partial clone and an ordinary clone of the same repository on different environments appearing in one sidebar project group.

    The local source checkout contains the shared suffix-tolerant parser fix, but the affected running binary still contains the old identity parser. No repository settings or live state were changed during diagnosis.

    Investigated with GPT-6 Astra through OpenCode in T3 Code.

  5. added a commit that references this issue on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions