dotnet/BenchmarkDotNet · error · DirectoryNotFoundException

{0} provided as ilcPackages does NOT exist

Error message

{0} provided as ilcPackages does NOT exist

What it means

Thrown by NativeAotToolchainBuilder.UseLocalBuild when the DirectoryInfo passed as ilcPackages does not exist on disk. This method configures the NativeAOT toolchain to consume a locally built ILCompiler from a .NET runtime source tree, and it unconditionally registers the path as a NuGet feed and pins the ILCompiler version. A missing directory makes package restore impossible, so it fails fast with DirectoryNotFoundException.

Source

Thrown at src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs:48

            if (nuGetFeedUrl.IsNotBlank())
                Feeds[Generator.NativeAotNuGetFeed] = nuGetFeedUrl;

            DisplayName(ilCompilerVersion.IsBlank() ? "Latest ILCompiler" : $"ILCompiler {ilCompilerVersion}");

            return this;
        }

        /// <summary>
        /// creates a NativeAOT toolchain targeting local build of ILCompiler
        /// Based on https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/nativeaot.md
        /// </summary>
        /// <param name="ilcPackages">the path to shipping packages, example: "C:\runtime\artifacts\packages\Release\Shipping"</param>
        [PublicAPI]
        public NativeAotToolchainBuilder UseLocalBuild(DirectoryInfo ilcPackages)
        {
            if (!ilcPackages.Exists)
                throw new DirectoryNotFoundException($"{ilcPackages} provided as {nameof(ilcPackages)} does NOT exist");

            Feeds["local"] = ilcPackages.FullName;
            ilCompilerVersion = "11.0.0-dev";
            Feeds["dotnet11"] = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json";
            useTempFolderForRestore = true;
            DisplayName("local ILCompiler build");

            return this;
        }

        /// <summary>
        /// The directory to restore packages to (optional).
        /// </summary>
        [PublicAPI]
        [SuppressMessage("ReSharper", "ParameterHidesMember")]
        public NativeAotToolchainBuilder PackagesRestorePath(string packagesRestorePath)
        {
            this.packagesRestorePath = packagesRestorePath;

View on GitHub (pinned to b515068b61)

Solutions

  1. Verify the directory exists before calling: check new DirectoryInfo(path).Exists and correct the path to point at the Shipping or Debug packages output (e.g. .../artifacts/packages/Release/Shipping)
  2. Build the .NET runtime locally first so the packages directory is populated (see dotnet/runtime nativeaot build docs)
  3. Use an absolute path to avoid working-directory ambiguity; print ilcPackages.FullName in a diagnostic to confirm what BDN actually resolves

Example fix

// before
var toolchain = NativeAotToolchain.CreateBuilder()
    .UseLocalBuild(new DirectoryInfo(@".\runtime\packages\Shipping")) // wrong path
    .ToToolchain();

// after (validate + absolute path)
var ilcPackages = new DirectoryInfo(@"C:\runtime\artifacts\packages\Release\Shipping");
if (!ilcPackages.Exists)
    throw new InvalidOperationException($"Build the runtime first; expected packages at {ilcPackages.FullName}");

var toolchain = NativeAotToolchain.CreateBuilder()
    .UseLocalBuild(ilcPackages)
    .ToToolchain();
Defensive patterns

Strategy: validation

Validate before calling

// Check the directory exists before handing it to UseLocalBuild.
using System.IO;
using BenchmarkDotNet.Toolchains.NativeAot;

static DirectoryInfo EnsureLocalBuildPackages(string path)
{
    var dir = new DirectoryInfo(Path.GetFullPath(path));
    if (!dir.Exists)
        throw new DirectoryNotFoundException(
            $"ILCompiler packages directory not found: {dir.FullName}. Build the runtime first.");
    if (dir.GetFiles("*.nupkg").Length == 0)
        throw new InvalidOperationException(
            $"Directory exists but contains no .nupkg files: {dir.FullName}");
    return dir;
}

var toolchain = NativeAotToolchain.CreateBuilder()
    .UseLocalBuild(EnsureLocalBuildPackages(@"C:\runtime\artifacts\packages\Release\Shipping"))
    .ToToolchain();

Try / catch

try { builder.UseLocalBuild(ilcPackages); }
catch (DirectoryNotFoundException ex) when (ex.Message.Contains("ilcPackages"))
{
    throw new InvalidOperationException(
        $"Local ILCompiler packages path is wrong or the runtime was not built: {ilcPackages.FullName}", ex);
}

Prevention

When it happens

Trigger: Calling NativeAotToolchain.CreateBuilder().UseLocalBuild(new DirectoryInfo(path)) where path does not resolve to an existing directory. The check is ilcPackages.Exists (DirectoryInfo.Exists, a live filesystem probe). Any non-existent path triggers it regardless of why it is missing.

Common situations: Pointing to C:\runtime\artifacts\packages\Release\Shipping before building the runtime locally. Using a relative path that resolves against an unexpected working directory. Reusing a path from another machine or after a 'git clean' removed build artifacts. Typing the Shipping vs Debug folder name wrong.

Related errors


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/fd8e383302319d23. Report an issue: GitHub.