Start Debugging
2026-01-23 dotnetdotnet-10

TreatWarningsAsErrors without sabotaging dev builds (.NET 10)

How to enforce TreatWarningsAsErrors in Release builds and CI while keeping Debug flexible for local development in .NET 10, using Directory.Build.props.

If you have ever flipped TreatWarningsAsErrors to true and immediately regretted it, you are not alone. A recent r/dotnet thread making the rounds suggests a simple adjustment: enforce warning-free code in Release (and CI), but keep Debug flexible for local exploration: https://www.reddit.com/r/dotnet/comments/1qjum3h/treating_warnings_as_errors_in_dotnet_the_right/

Release-only enforcement is a policy, not a toggle

What you are really trying to achieve is a workflow:

In .NET 10 repos, the cleanest place to centralize this is Directory.Build.props. That makes the rule apply to every project, including test projects, without copy/paste.

Here is a minimal pattern:

<!-- Directory.Build.props -->
<Project>
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>
</Project>

This matches what most CI pipelines build anyway (Release). If your CI builds Debug, switch it to Release first. That makes your “warning-free” bar match the binaries you ship.

Being strict does not mean being blind

Two knobs matter once you enable the big switch:

Example for tightening one warning while leaving the rest as warnings:

<Project>
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
    <WarningsAsErrors>$(WarningsAsErrors);CS8602</WarningsAsErrors>
  </PropertyGroup>
</Project>

And if you need to temporarily suppress a noisy analyzer in one project:

<Project>
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <NoWarn>$(NoWarn);CA2007</NoWarn>
  </PropertyGroup>
</Project>

If you are using Roslyn analyzers (common in modern .NET 10 solutions), also consider .editorconfig for severity control, because it is discoverable and keeps the policy close to the code:

# .editorconfig
[*.cs]
dotnet_diagnostic.CA2007.severity = warning

The practical payoff for PRs

The real win is predictable PR feedback. Developers learn quickly that warnings are not “future work”, they are part of the definition of done for Release. Debug stays fast and forgiving, Release stays strict and shippable.

If you want the original trigger for this pattern (and the tiny snippet that started the discussion), see the thread here: https://www.reddit.com/r/dotnet/comments/1qjum3h/treating_warnings_as_errors_in_dotnet_the_right/

< Back