Skip to content

.snupkg symbol packages never reach nuget.org — F11 debug-step-into broken for all consumers #259

Description

@Chris-Wolfgang

Symptom

Every published version of Wolfgang.TryPattern returns 404 for its .snupkg at the NuGet flat-container URL:

$ for v in 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4; do
    echo -n "v$v: "
    curl -sIo /dev/null -w "%{http_code}\n" \
      "https://api.nuget.org/v3-flatcontainer/wolfgang.trypattern/$v/wolfgang.trypattern.$v.snupkg"
  done
v0.3.0: 404
v0.3.1: 404
v0.3.2: 404
v0.3.3: 404
v0.3.4: 404

Meanwhile the .nupkg for every version returns 200 as expected.

Impact

F11 debug-step-into does not work for any consumer today. A consumer who installs Wolfgang.TryPattern, sets a breakpoint in their own code that calls the library, and presses F11 will land in "decompiled assembly" rather than the actual source served from GitHub via SourceLink — because their debugger cannot fetch the symbols.

Diagnosis so far

Local dotnet pack is fine. Running the release flow locally against main HEAD produces both artifacts:

Wolfgang.TryPattern.0.3.5.nupkg    (53,978 bytes)
Wolfgang.TryPattern.0.3.5.snupkg   (27,057 bytes, contains 4 PDBs)

The .snupkg's 4 PDBs all pass sourcelink test — SourceLink metadata is embedded correctly and URLs resolve to real GitHub raw content. So the ARTIFACT is fine; the problem is at the publish step.

Directory.Build.props is correct:

<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

.snupkg IS captured by the pipeline artifact. release.yaml's pack job uploads ./nuget-packages/ in full (if-no-files-found: warn), and publish-nuget downloads it into ./packages. Both files present in-flight.

The publish step MIGHT be the problem. release.yaml's publish loop:

$packages = Get-ChildItem -Path './packages' -Filter '*.nupkg' -ErrorAction SilentlyContinue
foreach ($package in $packages) {
    dotnet nuget push $package.FullName \
      --api-key $env:NUGET_API_KEY \
      --source https://api.nuget.org/v3/index.json \
      --skip-duplicate
}

Per NuGet docs, dotnet nuget push mypackage.nupkg should automatically push an adjacent mypackage.snupkg if it exists in the same directory. Both files ARE in ./packages/ at push time. But empirically the .snupkg either isn't being pushed or isn't being served at the flat-container URL after push.

Candidate root causes (needs investigation)

  1. dotnet nuget push symbol auto-push isn't happening for some reason — maybe the dotnet CLI version on the runner is too old, or the --skip-duplicate flag suppresses the symbol push, or the auto-push requires --symbol-source https://api.nuget.org/v3/index.json (undocumented?).
  2. .snupkg IS being pushed but nuget.org is serving it from a different URL (symbol server) than the flat container, and I'm querying the wrong path.
  3. .snupkg is being rejected during nuget.org's validation pipeline (the Package Symbol Server validates symbols separately and can silently reject).
  4. The recent PR #254 OIDC migration might affect symbol auth differently — but this issue predates ci(release): migrate NuGet publish to trusted publishing (OIDC) #254 (every version 0.3.0 through 0.3.4 was NUGET_API_KEY-based and all 404).

Reproduction

Public repro from any shell with curl:

curl -sIo /dev/null -w '%{http_code}\n' \
  "https://api.nuget.org/v3-flatcontainer/wolfgang.trypattern/0.3.4/wolfgang.trypattern.0.3.4.snupkg"
# → 404

curl -sIo /dev/null -w '%{http_code}\n' \
  "https://api.nuget.org/v3-flatcontainer/wolfgang.trypattern/0.3.4/wolfgang.trypattern.0.3.4.nupkg"
# → 200

Compare against a known-good published package with .snupkg symbols to sanity-check the URL pattern is right.

Acceptance criteria

  • Root cause identified: is dotnet nuget push failing silently to push .snupkg, or is nuget.org silently rejecting it, or is the URL query wrong?
  • release.yaml fixed so the next release publishes a real .snupkg reachable from consumers.
  • Verified by #181's SourceLink verification (which today runs against local artifacts) being augmented to also do a post-release fetch from nuget.org.
  • Fleet-wide check: verify whether other Wolfgang.* libraries have the same gap. If so, fix in repo-template and fan out.

Discovery context

Discovered while implementing #181 (SourceLink verification workflow). Filed as its own issue rather than folded into #181 because the .snupkg-publish gap is publish-side infrastructure, and the SourceLink verification workflow correctly focuses on build-side artifact integrity. Both matter; they're independent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    maintenance-taskA Maintenance sub-issue — actionable improvement work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions