PowerShell/PowerShell · critical · FileNotFoundException

{pwshPath}

Error message

{pwshPath}

What it means

Thrown by the .NET global-tool shim's Main when pwsh.dll is not present at the computed platform folder (./win/pwsh.dll or ./unix/pwsh.dll relative to the entry assembly directory). The tool package was installed but the runtime payload for the current OS is missing, so it cannot launch PowerShell.

Source

Thrown at src/Microsoft.PowerShell.GlobalTool.Shim/GlobalToolShim.cs:52

            var arguments = new List<string>(args.Length + 1);
            var pwshPath = Path.Combine(currentPath, platformFolder, PwshDllName);
            arguments.Add(pwshPath);
            arguments.AddRange(args);

            if (File.Exists(pwshPath))
            {
                Console.CancelKeyPress += (sender, e) =>
                {
                    e.Cancel = true;
                };

                var process = System.Diagnostics.Process.Start("dotnet", arguments);
                process.WaitForExit();
                return process.ExitCode;
            }
            else
            {
                throw new FileNotFoundException(pwshPath);
            }
        }
    }
}

View on GitHub (pinned to 3ff3c711bf)

Solutions

  1. Reinstall the tool: dotnet tool uninstall --global PowerShell then dotnet tool install --global PowerShell.
  2. Verify Path.Combine(toolDir, "win"|"unix", "pwsh.dll") exists after install.
  3. If packaging the tool yourself, ensure both win/pwsh.dll and unix/pwsh.dll are included in the nupkg.
  4. Run from a clean tool directory to rule out a stale partial layout.

Example fix

// before (manual launch)
Process.Start("dotnet", pwshPath);

// after
if (!File.Exists(pwshPath))
    throw new FileNotFoundException($"pwsh.dll not found at {pwshPath}. Reinstall the global tool: dotnet tool uninstall -g PowerShell; dotnet tool install -g PowerShell", pwshPath);
Process.Start("dotnet", arguments);
Defensive patterns

Strategy: validation

Validate before calling

string pwshPath = Path.Combine(toolDir, OperatingSystem.IsWindows() ? "win" : "unix", "pwsh.dll");
if (!File.Exists(pwshPath))
    throw new FileNotFoundException($"pwsh.dll missing at {pwshPath}. Reinstall: dotnet tool uninstall -g PowerShell; dotnet tool install -g PowerShell", pwshPath);

Type guard

static bool PwshPayloadPresent(string toolDir) =>
    File.Exists(Path.Combine(toolDir, OperatingSystem.IsWindows() ? "win" : "unix", "pwsh.dll"));

Try / catch

try { return EntryPoint.Main(args); }
catch (FileNotFoundException ex) { Console.Error.WriteLine($"{ex.Message}. Reinstall the global tool."); return 1; }

Prevention

When it happens

Trigger: Running `pwsh` (dotnet global tool) after a partial/corrupt install; a custom packaging that dropped the win/ or unix/ subfolder; deploying the global-tool nupkg without bundling the OS-specific pwsh.dll.

Common situations: dotnet tool install failed mid-way and left a partial layout; the tool was copied by hand without the per-OS folder; a CI image uses a trimmed global tool package.

Related errors


AI-assisted analysis of PowerShell/PowerShell@3ff3c711bf (2026-08-13). Data as JSON: /api/errors/79f1f29c52863227. Report an issue: GitHub.