Treat warnings as errors in Debug mode when an AI agent is detected

Treating warnings as errors is good practice for both humans and AI agents — it keeps the codebase honest. Pair it with an opinionated .editorconfig and analyzers like StyleCop, SonarCloud, or Meziantou, and you get consistent code with clear, actionable diagnostics from the compiler and the Roslyn analysis pipeline.

The catch is that having warnings-as-errors on all the time in Debug mode is annoying when you are the one developing. When I am refactoring or moving code around, I do not want to stop and fix every style nit right away. A few warnings during local development are fine — I clean them up before I push.

For AI agents the trade-off is different. Some agents will notice and act on warnings, especially if you tell them to, but in my experience most just check whether the build succeeded and move on. Warnings pile up silently, and I only find out when CI fails — at which point the agent has already built on top of those changes and fixing them gets more expensive. Promoting warnings to errors removes the ambiguity: the build either passes or it does not. Each analyzer diagnostic comes with a description of what is wrong and often a suggested code fix, which is exactly the kind of feedback an agent can act on immediately.

So the setup I want is: warnings-as-errors always on in Release and CI, off in Debug for humans, and on in Debug for agents.

The MSBuild setup

In the root Directory.Build.props, I keep two property groups.

The first one is the existing Release/CI guard that has been there for years:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

The second one enables the same setting in non-Release builds when a known agent environment variable is present:

<!--
  Also treat warnings as errors in non-Release builds when a coding agent is
  driving the session. This stops agents from silently introducing warnings
  that only surface later in CI.
-->
<PropertyGroup Condition="'$(Configuration)' != 'Release'
  and ('$(COPILOT_CLI)' != ''
    or '$(COPILOT_AGENT_SESSION_ID)' != ''
    or '$(CLAUDECODE)' != ''
    or '$(CLAUDE_CODE)' != ''
    or '$(CODEX_SANDBOX)' != ''
    or '$(CODEX_CLI)' != ''
    or '$(AIDER)' != ''
    or '$(CURSOR_AGENT)' != '')">
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

MSBuild reads environment variables as properties, so $(COPILOT_CLI) evaluates to the value of the COPILOT_CLI environment variable. If the variable is set, the condition is true and warnings become errors.

The agent environment variables are the same ones I use in the AgentDiffGuard from my previous post about disabling the diff tool for Verify snapshot tests. The pattern is the same: detect that an agent is running and adjust behavior accordingly.

The result

Three modes, one Directory.Build.props:

No extra tooling, no custom MSBuild targets, just a conditional property group that reads the environment.

Hope this helps.

Comments