Skip to content

Clone: surface the real clone failure instead of a misleading InvalidDataException#2070

Closed
ShiningMassXAcc wants to merge 1 commit into
microsoft:masterfrom
ShiningMassXAcc:user/nbaird/63117974-gvfs-clone-error-output
Closed

Clone: surface the real clone failure instead of a misleading InvalidDataException#2070
ShiningMassXAcc wants to merge 1 commit into
microsoft:masterfrom
ShiningMassXAcc:user/nbaird/63117974-gvfs-clone-error-output

Conversation

@ShiningMassXAcc

Copy link
Copy Markdown
Member

Summary

gvfs clone <url> <dst> --branch <nonexistent-branch> printed a misleading
downstream exception instead of the real, actionable failure. The console showed:

Cannot clone @ c:\s\osbr: System.IO.InvalidDataException: Couldn't open repo at C:\s\osbr\src: failed to resolve path 'C:\s\osbr\src': The system cannot find the file specified.
   at GVFS.Common.Git.LibGit2Repo..ctor(ITracer, String)
   ...
   at GVFS.CommandLine.CloneVerb.Execute()

…while the real error was only in the clone log, one line above an even-more-downstream warning:

[Error]   {"ErrorMessage":"Remote branch official/br_current_directes_dev not found in upstream origin"}
[Warning] {"WarningMessage":"Couldn't open repo at C:\s\osbr\src: failed to resolve path ..."}

Root cause

In CloneVerb.Execute() the LibGit2RepoInvoker for the enlistment src folder
was constructed unconditionally, even after cloneResult.Success == false. On a
failed clone the src working directory was never created, so LibGit2Repo's
constructor logged a Couldn't open repo at ...\src warning and threw an
InvalidDataException. That exception escaped the using (tracer) scope, bypassing
the existing else branch that prints Error: <real message>, and was caught by the
generic catch (Exception) handler that printed the misleading Cannot clone @ ...: InvalidDataException: Couldn't open repo message.

Fix

Guard the LibGit2RepoInvoker construction behind cloneResult.Success (and
initialize trustPackIndexes = false, since it is only read on the success path).
Failed clones now fall through to the existing else branch, which already prints
the real error:

Cannot clone @ c:\s\osbr
Error: Remote branch official/br_current_directes_dev not found in upstream origin

Tests

Added CloneTests.CloneWithNonExistentBranchFailsWithBranchError, which clones with a
non-existent --branch and asserts:

  • exit code is the generic error (3),
  • output contains Remote branch ... not found in upstream origin,
  • output does not contain Couldn't open repo / InvalidDataException.

Validation

  • dotnet build GVFS/GVFS/GVFS.csproj -c Debug — succeeded (0 errors).
  • GVFS.FunctionalTests C# compiles; the new test exercises the fixed path (requires
    the full functional-test harness to execute).

Tracked by ADO Task 63117974 (parent Deliverable 60994157 — "Git reliability for razzle").

…DataException

When 'gvfs clone --branch <nonexistent>' failed, CloneVerb.Execute constructed a
LibGit2RepoInvoker against the enlistment's src folder unconditionally - even
after the clone had already failed. On a failed clone that src folder was never
created, so opening it logged a "Couldn't open repo at ...\src" warning and threw
an InvalidDataException. That exception escaped the tracer scope, bypassing the
else branch that prints the real error, and was caught by the generic handler
which printed the misleading "Cannot clone @ ...: InvalidDataException: Couldn't
open repo" message. The actionable error ("Remote branch ... not found in
upstream origin") was only written to the clone log.

Guard the LibGit2RepoInvoker construction behind cloneResult.Success so failed
clones fall through to the existing else branch that prints the real error. Add a
functional test asserting the branch-not-found error is shown and the misleading
messages are not.
@tyrielv

tyrielv commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

I suspect this is a duplicate of #2065

@ShiningMassXAcc

Copy link
Copy Markdown
Member Author

Confirmed duplicate of #2065 — thanks @tyrielv. #2065 targets the same root cause in CloneVerb.Execute() (the unconditional LibGit2RepoInvoker construction on a failed clone) and gates the trustPackIndexes lookup on cloneResult.Success, so the branch-not-found case handled here now also falls through to the real Error: Remote branch ... not found in upstream origin message. #2065 additionally fixes the null-enlistment NRE and applies the same cleanup to PrefetchVerb/Hooks/Mount. Closing in favor of #2065.

@ShiningMassXAcc
ShiningMassXAcc deleted the user/nbaird/63117974-gvfs-clone-error-output branch July 20, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants