Repository navigation
Explicit Microsoft.SourceLink.GitHub PackageReference silently disables SourceLink on .NET 8+ SDKs #1652
Description
Summary
On SDKs that bundle SourceLink as implicit SDKs (.NET 8+), adding an explicit <PackageReference Include=\"Microsoft.SourceLink.GitHub\" PrivateAssets=\"all\" /> silently disables SourceLink rather than enabling or replacing it. Build succeeds with no warnings, but resulting packages have:
- No SourceLink JSON in the PDB
- No PathMap normalization (paths remain non-deterministic)
Reproducibledebug entry is still set, so the PE looks deterministic by header, but embedded source paths are not mapped
The docs (both the README and many blog posts/templates) still instruct users to add this package. On a modern SDK, following that guidance breaks SourceLink.
Environment
- .NET SDK:
10.0.202(also confirmed in11.0.100-preview.2) Microsoft.SourceLink.GitHubNuGet package:10.0.202- Central Package Management via
Directory.Packages.propswithGlobalPackageReference - Strong-named, multi-targeted library (
netstandard2.0;net8.0;net9.0;net10.0)
Reproduction
Directory.Packages.props:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<GlobalPackageReference Include=\"Microsoft.SourceLink.GitHub\" Version=\"10.0.202\" PrivateAssets=\"all\" />
</ItemGroup>
</Project>Directory.Build.props:
<Project>
<PropertyGroup>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
</Project>Then dotnet build -c Release. Inspect the produced PDB — no SourceLink custom debug information entry (CC110556-A091-4D38-9FEC-25AB9A351A6A), no obj/*/*.sourcelink.json file.
Root cause trace
- NuGet restores
Microsoft.SourceLink.GitHubdirectly and imports itsbuild/Microsoft.SourceLink.GitHub.props/.targets. - Its transitive deps (
Microsoft.SourceLink.Common,Microsoft.Build.Tasks.Git) resolve inproject.assets.jsonas\"buildTransitive/_._\": {}— the empty-assets marker — becausedevelopmentDependency=truepackages don't flow their build assets through aPrivateAssets=allparent. Common'sInitializeSourceControlInformation.targets/Microsoft.SourceLink.Common.targetsnever get imported via NuGet. - NuGet still generates the
PkgMicrosoft_SourceLink_Commonpath property (from restore), even though its build assets are_._. - The SDK-bundled
Microsoft.NET.Sdk.SourceLink.propscontains:Because<SuppressImplicitGitSourceLink Condition=\"'$(PkgMicrosoft_SourceLink_Common)' != ''\">true</SuppressImplicitGitSourceLink> <ImportGroup Condition=\"'$(SuppressImplicitGitSourceLink)' != 'true'\"> <Import Project=\"...\Microsoft.Build.Tasks.Git\build\Microsoft.Build.Tasks.Git.props\" /> <Import Project=\"...\Microsoft.SourceLink.Common\build\Microsoft.SourceLink.Common.props\" /> <Import Project=\"...\Microsoft.SourceLink.GitHub\build\Microsoft.SourceLink.GitHub.props\" /> ... </ImportGroup>
PkgMicrosoft_SourceLink_Commonis now set,SuppressImplicitGitSourceLink=truefires → SDK's bundledCommonandMicrosoft.Build.Tasks.Gitimports are skipped.
Net result: GitHub.targets is imported alone, without the LocateRepository task or the InitializeSourceControlInformationFromSourceControlManager target. @(SourceRoot) is never populated → _GenerateSourceLinkFile does nothing → /sourcelink: switch is never passed to csc → no SourceLink CDI in PDB → paths are not PathMap-normalized.
Full preprocess (msbuild -pp) and PE-debug-directory verification available in thomhurst/TUnit#5579.
Fix that worked for us
Remove the explicit Microsoft.SourceLink.GitHub PackageReference entirely. The SDK then auto-imports Common + Build.Tasks.Git + GitHub from $(DotnetRoot)/sdk/<ver>/Sdks/Microsoft.SourceLink.*, and everything works.
Suggested improvements
Any one of these would have made this far easier to diagnose:
- Docs: Update the README to say "on .NET SDK 8+, don't add
Microsoft.SourceLink.GitHub— it's implicit; add it only for older SDKs or custom hosts." - Warning: Have
Microsoft.SourceLink.GitHub.targetsemit a warning if it's imported butMicrosoft.SourceLink.Common.targetshasn't been imported (detectable by a well-known property set in Common's targets). This would catch thebuildTransitive/_._scenario. - Suppression condition: Narrow the SDK's
SuppressImplicitGitSourceLinkcheck so it only fires when Common's build assets actually imported, not merely when thePkg*path property is set (since NuGet sets that even for_._assets).
Happy to contribute a docs PR if helpful.
Activity
thomhurst commentedon Apr 16, 2026
Just so you can see how simple, and also how counter-intuitive the fix was, this was the change that fixes the sourcelink + deterministic nuget packages for me: https://github.com/thomhurst/TUnit/pull/5579/changes
Use Visitor.Run pattern (#39)
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference
Remove explicit Microsoft.SourceLink.GitHub package reference