dotnet/reactive · error · DirectoryNotFoundException

PlugIn host build output folder not found at

Error message

PlugIn host build output folder not found at {plugInHostExecutableFolder}

What it means

PlugInHost.Run computes the host executable folder (bin/{Configuration}/{hostRuntimeTfm}/) and throws DirectoryNotFoundException when that build output folder is missing, meaning the launcher project was not built for the requested configuration and TFM.

Solutions

  1. Build the launcher project for the exact Configuration and TFM being requested (e.g. dotnet build -c Release -f net46)
  2. Run the check with a configuration/TFM that has build output
  3. Verify bin/{Configuration}/{hostRuntimeTfm}/ exists for the launcher before running

Example fix

// before
var result = await host.Run("net46"); // bin/Release/net46 missing
// after
dotnet build Rx.NET/Test/Gauntlet/Checks/PlugIns/PlugIn.HostNetFx -c Release -f net46
var result = await host.Run("net46");
Defensive patterns

Strategy: validation

Validate before calling

var outDir = Path.Combine(plugInsRoot, launcher, $"bin/{Configuration}/{hostRuntimeTfm}/");
if (!Directory.Exists(outDir)) throw new DirectoryNotFoundException($"Build the host first: {outDir}");

Try / catch

try { await host.Run(tfm); }
catch (DirectoryNotFoundException ex) when (ex.Message.Contains("build output folder not found")) { /* rebuild for this Configuration/TFM */ }

Prevention

When it happens

Trigger: Running the Gauntlet plug-in check for a configuration/TFM combination that was never built (e.g. Release output absent, or the specific net4x folder not produced).

Common situations: Building only Debug but running with Configuration=Release, a TFM whose host project doesn't target it, or cleaning output before the check.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/458814e25b6f0404. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Test/Gauntlet/Checks/PlugIns/PlugIn.HostDriver/PlugInHost.cs:109

            Path.Combine(AppContext.BaseDirectory, "../../../../"));
        if (!plugInsFolder.Exists)
        {
            throw new DirectoryNotFoundException($"PlugIns folder not found: {plugInsFolder.FullName}");
        }

        var plugInHostProjectFolder = Path.Combine(
            plugInsFolder.FullName,
            launcher);
        if (!Directory.Exists(plugInHostProjectFolder))
        {
            throw new DirectoryNotFoundException($"PlugIn host project folder not found at {plugInHostProjectFolder}");
        }
        var plugInHostExecutableFolder = Path.Combine(
            plugInHostProjectFolder,
            $"bin/{Configuration}/{hostRuntimeTfm}/");
        if (!Directory.Exists(plugInHostExecutableFolder))
        {
            throw new DirectoryNotFoundException($"PlugIn host build output folder not found at {plugInHostExecutableFolder}");
        }

        var plugInHostExecutablePath = Path.Combine(
            plugInHostExecutableFolder,
            $"{launcher}.exe");
        if (!File.Exists(plugInHostExecutablePath))
        {
            throw new FileNotFoundException($"PlugIn host executable not found at {plugInHostExecutablePath}");
        }

        var firstPlugInPath = await _plugInBuilder.GetPlugInDllPathAsync(firstPlugIn);
        var secondPlugInPath = await _plugInBuilder.GetPlugInDllPathAsync(secondPlugIn);

        var startInfo = new ProcessStartInfo
        {
            FileName = plugInHostExecutablePath,
            RedirectStandardOutput = true,
            UseShellExecute = false,

View on GitHub (pinned to 94b5d5ab91)