Description
Describe the bug
Starting with .NET SDK 8.0.409, dotnet format
can no longer format source files of a .csproj with no Sdk
attribute on the Project
element if Mono is installed. dotnet format
outputs a stack trace and the source file is not formatted:
Unhandled exception: System.Exception: The build host could not be found at '/usr/share/dotnet/sdk/8.0.409/DotnetTools/dotnet-format/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe'
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.AssertBuildHostExists(String buildHostPath)
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetDotNetFrameworkBuildHostPath()
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.CreateMonoBuildHostStartInfo()
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostAsync(BuildHostProcessKind buildHostKind, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostWithFallbackAsync(BuildHostProcessKind buildHostKind, String projectOrSolutionFilePath, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Workspaces.MSBuildWorkspaceLoader.LoadAsync(String solutionOrProjectPath, WorkspaceType workspaceType, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
This affects both Ubuntu (22.04) and macOS (15.5).
The issue does not reproduce with .NET SDK 8.0.408. It also does not reproduce if Mono is not installed, although an additional warning message is emitted starting with .NET SDK 8.0.409:
[Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager] An installation of Mono could not be found; /opt/work/helloworld.csproj will be loaded with the .NET Core SDK and may encounter errors.
It appears that the dotnet format
command has worked with this older .csproj syntax (example) up until now, although I'm not sure if it's expected to work against a .csproj that wasn't created by dotnet new
and if it's considered a bug that it no longer works. At the very least, I'd say it's a bug that it outputs a stack trace instead of an error message.
To Reproduce
- Create a
Dockerfile
file with the following contents:
ARG DOTNET_SDK_VERSION=8.0.409
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_SDK_VERSION}-jammy-amd64
# Install Mono
ARG WITHOUT_MONO
RUN if [ -z "$WITHOUT_MONO" ]; then \
apt-get update && \
apt-get install -y gnupg && \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" > /etc/apt/sources.list.d/mono-official-stable.list && \
apt-get update && \
apt-get install -y mono-complete ; \
fi
# Run dotnet format (with a minimal MSBuild project file)
# https://learn.microsoft.com/en-us/visualstudio/msbuild/walkthrough-creating-an-msbuild-project-file-from-scratch?view=vs-2022#create-a-minimal-msbuild-project-file
WORKDIR /opt/work
RUN cat > helloworld.csproj <<EOF
<Project>
<ItemGroup>
<Compile Include="helloworld.cs"/>
</ItemGroup>
<Target Name="Build">
<Csc Sources="@(Compile)"/>
</Target>
</Project>
EOF
RUN cat > helloworld.cs <<EOF
using System;
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello, world!"); // bad indentation
}
}
EOF
RUN bash <<EOF
set -x
dotnet --info
dotnet format helloworld.csproj -v diag
echo "dotnet exit status: \$?"
cat helloworld.cs
false
EOF
- Run
docker build . --platform linux/amd64
. - Observe that
dotnet format
did not formathelloworld.cs
and output an unhandled exception:
...
0.128 + dotnet --info
0.603 .NET SDK:
0.604 Version: 8.0.409
0.604 Commit: 5f0de3de48
0.741 Workload version: 8.0.400-manifests.def3829e
0.742 MSBuild version: 17.11.31+933b72e36
0.742
0.742 Runtime Environment:
0.746 OS Name: ubuntu
0.746 OS Version: 22.04
0.749 OS Platform: Linux
0.763 RID: linux-x64
0.763 Base Path: /usr/share/dotnet/sdk/8.0.409/
0.763
0.763 .NET workloads installed:
0.768 Configured to use loose manifests when installing new manifests.
0.768 There are no installed workloads to display.
0.775
0.775 Host:
0.775 Version: 8.0.16
0.775 Architecture: x64
0.775 Commit: efd5742bb5
0.775
0.775 .NET SDKs installed:
0.775 8.0.409 [/usr/share/dotnet/sdk]
0.775
0.775 .NET runtimes installed:
0.775 Microsoft.AspNetCore.App 8.0.16 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
0.775 Microsoft.NETCore.App 8.0.16 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
0.775
0.775 Other architectures found:
0.775 None
0.775
0.775 Environment variables:
0.775 Not set
0.775
0.775 global.json file:
0.775 Not found
0.775
0.775 Learn more:
0.775 https://aka.ms/dotnet/info
0.775
0.775 Download .NET:
0.775 https://aka.ms/dotnet/download
0.779 + dotnet format helloworld.csproj -v diag
2.105 The dotnet runtime version is '8.0.16'.
2.645 The dotnet CLI version is '8.0.409'.
2.716 Using MSBuild.exe located in '/usr/share/dotnet/sdk/8.0.409/'.
2.722 Formatting code files in workspace '/opt/work/helloworld.csproj'.
2.722 Loading workspace.
3.799
4.739 Unhandled exception: System.Exception: The build host could not be found at '/usr/share/dotnet/sdk/8.0.409/DotnetTools/dotnet-format/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe'
4.755 at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.AssertBuildHostExists(String buildHostPath)
4.755 at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetDotNetFrameworkBuildHostPath()
4.755 at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.CreateMonoBuildHostStartInfo()
4.755 at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostAsync(BuildHostProcessKind buildHostKind, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostWithFallbackAsync(BuildHostProcessKind buildHostKind, String projectOrSolutionFilePath, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.Tools.Workspaces.MSBuildWorkspaceLoader.LoadAsync(String solutionOrProjectPath, WorkspaceType workspaceType, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
4.755 at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
4.755 at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
4.755 at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
4.808 + echo 'dotnet exit status: 1'
4.808 dotnet exit status: 1
4.808 + cat helloworld.cs
4.820 using System;
4.820
4.820 class HelloWorld
4.820 {
4.820 static void Main()
4.820 {
4.820 Console.WriteLine("Hello, world!"); // bad indentation
4.820 }
4.820 }
...
Run docker build . --platform linux/amd64 --build-arg WITHOUT_MONO=1
to run the test again without Mono installed and observe that dotnet format
does format helloworld.cs
(even if it outputs a warning message):
...
0.781 + dotnet format helloworld.csproj -v diag
...
2.798 Formatting code files in workspace '/opt/work/helloworld.csproj'.
2.798 Loading workspace.
3.925
6.150 [Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager] An installation of Mono could not be found; /opt/work/helloworld.csproj will be loaded with the .NET Core SDK and may encounter errors.
6.150 Msbuild failed when processing the file '/opt/work/helloworld.csproj' with message: Project does not contain 'Compile' target.
6.153 Complete in 3353ms.
6.153 Determining formattable files.
6.345 Complete in 193ms.
6.345 Running formatters.
...
8.114 Formatted code file '/opt/work/helloworld.cs'.
8.191 Formatted 1 of 1 files.
8.191 Format complete in 5392ms.
8.259 + echo 'dotnet exit status: 0'
8.259 dotnet exit status: 0
8.260 + cat helloworld.cs
8.271 using System;
8.271
8.271 class HelloWorld
8.271 {
8.271 static void Main()
8.271 {
8.271 Console.WriteLine("Hello, world!"); // bad indentation
8.271 }
8.271 }
...
Run docker build . --platform linux/amd64 --build-arg DOTNET_SDK_VERSION=8.0.408
to run the test again with .NET SDK 8.0.408 (and Mono installed) and observe that dotnet format
does format helloworld.cs
:
...
0.116 + dotnet --info
0.593 .NET SDK:
0.593 Version: 8.0.408
0.593 Commit: e6663e9b3d
0.729 Workload version: 8.0.400-manifests.22ac4dbc
0.730 MSBuild version: 17.11.26+2b19be476
...
0.767 + dotnet format helloworld.csproj -v diag
2.077 The dotnet runtime version is '8.0.15'.
2.607 The dotnet CLI version is '8.0.408'.
2.683 Using MSBuild.exe located in '/usr/share/dotnet/sdk/8.0.408/'.
2.689 Formatting code files in workspace '/opt/work/helloworld.csproj'.
2.689 Loading workspace.
3.760
4.941 Msbuild failed when processing the file '/opt/work/helloworld.csproj' with message: Project does not contain 'Compile' target.
4.945 Complete in 2254ms.
4.945 Determining formattable files.
5.132 Complete in 188ms.
5.132 Running formatters.
...
6.691 Formatted code file '/opt/work/helloworld.cs'.
6.726 Formatted 1 of 1 files.
6.726 Format complete in 4036ms.
6.790 + echo 'dotnet exit status: 0'
6.790 + cat helloworld.cs
6.790 dotnet exit status: 0
6.802 using System;
6.802
6.802 class HelloWorld
6.802 {
6.802 static void Main()
6.802 {
6.802 Console.WriteLine("Hello, world!"); // bad indentation
6.802 }
6.802 }
...
Exceptions (if any)
Unhandled exception: System.Exception: The build host could not be found at '/usr/share/dotnet/sdk/8.0.409/DotnetTools/dotnet-format/BuildHost-net472/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe'
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.AssertBuildHostExists(String buildHostPath)
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetDotNetFrameworkBuildHostPath()
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.CreateMonoBuildHostStartInfo()
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostAsync(BuildHostProcessKind buildHostKind, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.BuildHostProcessManager.GetBuildHostWithFallbackAsync(BuildHostProcessKind buildHostKind, String projectOrSolutionFilePath, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(String projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadProjectInfoAsync(String projectFilePath, ProjectMap projectMap, IProgress`1 progress, ILogger msbuildLogger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenProjectAsync(String projectFilePath, ILogger msbuildLogger, IProgress`1 progress, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Workspaces.MSBuildWorkspaceLoader.LoadAsync(String solutionOrProjectPath, WorkspaceType workspaceType, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
Further technical details
- Include the output of
dotnet --info
.NET SDK:
Version: 8.0.409
Commit: 5f0de3de48
Workload version: 8.0.400-manifests.def3829e
MSBuild version: 17.11.31+933b72e36
Runtime Environment:
OS Name: ubuntu
OS Version: 22.04
OS Platform: Linux
RID: linux-x64
Base Path: /usr/share/dotnet/sdk/8.0.409/
.NET workloads installed:
Configured to use loose manifests when installing new manifests.
There are no installed workloads to display.
Host:
Version: 8.0.16
Architecture: x64
Commit: efd5742bb5
.NET SDKs installed:
8.0.409 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.16 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.16 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
The IDE (VS / VS Code/ VS4Mac) you're running on, and its version