Skip to content

6.3.0 marks Microsoft.ML.OnnxRuntime.Gpu and its dependencies as development-only (scope="excluded"), so --exclude-dev drops a shipped runtime package #1139

Closed

Description

@wahyuen

Since 6.3.0 (#1138), a project that references Microsoft.ML.OnnxRuntime.Gpu gets that package and its whole dependency tree marked scope="excluded". With --exclude-dev, the BOM comes out empty. 6.2.0 and 6.2.1 mark the same packages required.

These packages ship. A dotnet publish puts Microsoft.ML.OnnxRuntime.dll, libonnxruntime.so and the provider libraries in the output, and the app crashes on start without them.

Microsoft.ML.OnnxRuntime.Gpu has no lib/runtime assets of its own, only buildTransitive props and targets. Its dependencies carry the real files. My guess is the new check reads "no runtime assets" as development-only, then carries that down to the dependencies.

Steps to reproduce

dotnet new console -n Repro --framework net10.0
cd Repro
dotnet add package Microsoft.ML.OnnxRuntime.Gpu --version 1.25.1

Replace Program.cs with:

using Microsoft.ML.OnnxRuntime;
Console.WriteLine(OrtEnv.Instance().GetVersionString());

Then:

dotnet build
dotnet-CycloneDX Repro.csproj -o out -fn bom.json -F Json
dotnet-CycloneDX Repro.csproj -o out-ed -fn bom.json -F Json -ed

The result is the same with the template's default Program.cs.

Results

Version No flag --exclude-dev
6.2.0 all 5 components required all 5 components
6.2.1 all 5 components required all 5 components
6.3.0 all 5 components excluded no components

The 5 components are Microsoft.ML.OnnxRuntime.Gpu, .Gpu.Linux, .Gpu.Windows, .Managed and System.Numerics.Tensors.

Expected: all 5 are required, as in 6.2.x, because they end up in the published output.

Environment: .NET SDK 10, net10.0, Windows 11.

Activity

  1. wahyuen commented on Oct 12, 2026

    @wahyuen
    Author

    I think I've found where it comes from, in ProjectAssetsFileService.cs at v6.3.0.

    1. SetIsDevDependency (L131-L168) returns true when a package has no runtime-capable assets and has build assets:

      return !hasRuntimeCapableAssets && (hasBuildOnlyAssets || (selected & runtimeCategories) == 0);

      Microsoft.ML.OnnxRuntime.Gpu is a meta-package. Its only assets are buildTransitive/netstandard2.1/Microsoft.ML.OnnxRuntime.Gpu.props and .targets, so it's marked as a dev dependency even though it's a plain direct PackageReference.

    2. The reachability walk (L181) only starts from direct references that aren't dev dependencies:

      foreach (var package in packages.Where(p => p.IsDirectReference && !p.IsDevDependency))

      The meta-package is never a starting point, so .Gpu.Linux, .Gpu.Windows, .Managed and System.Numerics.Tensors are never reached, and they all become excluded too, although they carry the runtime and native assets.

    A package that only carries build assets but has dependencies that carry runtime or native assets probably shouldn't count as development-only. Treating a direct reference with the default IncludeAssets/PrivateAssets as runtime would fix this case too.

  2. added a commit that references this issue on Oct 12, 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

    triageDon't know what to do with this yet

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions