Skip to main content

authoring-errors-and-warnings

Guides authoring of MSBuild errors, warnings, diagnostic messages, and internal assertions. Consult when adding new MSBxxxx codes, writing or modifying user-facing diagnostic text, using Assumed for internal invariants, deciding between error/warning/message severity, working with Strings.resx resource files, formatting paths in error output, or evaluating whether a new warning could break WarnAsError builds.

ソース情報

リポジトリ
dotnet/msbuild
ソースの最終更新活動
2026年11月6日 16:01
検出された SKILL.md の言語
英語
スター
5,553
フォーク
1,460

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
authoring-errors-and-warnings
description
Guides authoring of MSBuild errors, warnings, diagnostic messages, and internal assertions. Consult when adding new MSBxxxx codes, writing or modifying user-facing diagnostic text, using Assumed for internal invariants, deciding between error/warning/message severity, working with Strings.resx resource files, formatting paths in error output, or evaluating whether a new warning could break WarnAsError builds.
argument-hint
Describe the error/warning or internal assertion being added or modified.
# Error, Warning, and Assertion Authoring in MSBuild User-facing error messages are MSBuild's primary user interface. They must help developers fix problems without reading source code. For the mechanics of error code assignment, see [assigning-msb-error-code.md](../../../documentation/assigning-msb-error-code.md). ## Internal Assertions Use [`Assumed`](../../../src/Framework/Assumed.cs) to check internal invariants whose violation indicates an MSBuild bug, not invalid user input. - `Assumed.True`, `Assumed.False`, `Assumed.NotNull`, and related helpers throw `InternalErrorException` on failure in both Debug and Release builds. - Assertion messages are non-localized developer diagnostics. Do not assign an `MSBxxxx` code or add `Strings.resx` or `.xlf` entries for these checks. - Do not replace project, command-line, or public API input validation with `Assumed`; preserve the appropriate user-facing diagnostic or argument exception. ```csharp Assumed.True(_initialized, "State must be initialized before use."); ``` Pass interpolated assertion messages directly to the helper so its conditional interpolated string handler can avoid formatting when the assertion succeeds. The quality, severity, resource, and localization rules below apply to user-facing diagnostics. ## Error Message Quality Rules Every user-facing error message must answer three questions: 1. **What happened?** — State the problem clearly 2. **Why?** — Provide context (file, property, expected value) 3. **What should the user do?** — Give actionable guidance ```xml <!-- BAD: What is "it"? What should I do? --> <value>MSB4999: Invalid configuration.</value> <!-- GOOD: States the problem, context, and fix --> <value>MSB4999: The project "{0}" specifies TargetFramework "{1}" which is not installed. Install the SDK for "{1}" or update the TargetFramework in the project file.</value> ``` ## Severity Decision Framework ``` Is the condition always wrong (for example, invalid project input)? ├── Yes → ERROR (build should fail) └── No ├── Could this cause subtle build correctness issues? │ ├── Yes, likely → WARNING (but see WarnAsError impact below) │ └── Yes, maybe → MESSAGE at Normal importance └── Is this purely informational? └── Yes → MESSAGE at Low importance ``` ### The WarnAsError Constraint **New warnings are breaking changes** for builds using: - `-WarnAsError` (CLI) - `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` (project) - `<WarningsAsErrors>MSBxxxx</WarningsAsErrors>` (specific codes) Before adding a new warning, consider: 1. **Is the warning important enough to justify breaking WarnAsError builds?** If yes, gate behind a ChangeWave (see [changewaves skill](../changewaves/SKILL.md)). 2. **Could this be a Message instead?** Messages never break builds but still appear in binary logs. 3. **Should this be an error from the start?** If the condition is always wrong, skip the warning stage. ## MSB Error Code Assignment ### Code Ranges | Range | Area | |-------|------| | `MSB1xxx` | Command-line handling | | `MSB3xxx` | Tasks (`Microsoft.Build.Tasks.Core.dll`) | | `MSB4xxx` | Engine (`Microsoft.Build.dll`) | | `MSB5xxx` | Shared code across assemblies | | `MSB6xxx` | Utilities (`Microsoft.Build.Utilities`) | ### Assignment Process 1. Open the `Strings.resx` file for the appropriate assembly 2. Find the "Next message code" comment at the bottom of the file 3. Search the repo to confirm the code is not already in use 4. Use the code; update the comment to the next available number See [assigning-msb-error-code.md](../../../documentation/assigning-msb-error-code.md) for detailed steps. ## Resource String Format ```xml <data name="FeatureArea.DescriptiveName"> <value>MSBxxxx: Clear description with {0} placeholders for runtime values.</value> <comment>{StrBegin="MSBxxxx: "}{0} is the project file path. {1} is the property name.</comment> </data> ``` ### Rules - Resource name uses `FeatureArea.DescriptiveName` convention - Value starts with `MSBxxxx: ` (code, colon, space) - Comment documents the `{StrBegin}` marker and explains each `{N}` placeholder - Comments guide translators — mention untranslatable tokens ## Consuming Error Resources in Code Use the standard formatting method that extracts and applies the error code. Engine-level project errors use `Microsoft.Build.Internal.ProjectErrorUtilities`: ```csharp // For errors Log.LogErrorWithCodeFromResources("Copy.Error", sourceFile, destFile, ex.Message); // For warnings Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.Conflict", assemblyName); // For engine-level errors (not in tasks) ProjectErrorUtilities.ThrowInvalidProject( elementLocation, "InvalidProjectFile", arg1, arg2); ``` **Never** construct user-facing error messages by string concatenation — always use resource strings for localization support. ## Localization Requirements - Error **codes** (`MSBxxxx`) are never localized - User-facing error **text** is localized into all supported languages - After adding/modifying resource strings, run a full build to generate `.xlf` placeholder translations - Use `<comment>` elements to help translators understand context - See [Localization.md](../../../documentation/wiki/Localization.md) for the full localization process ## Path Formatting in Error Messages - Show paths relative to the project directory when possible - Use the path exactly as the user specified it (don't normalize slashes) - Include file and line number via `IElementLocation` when available — this enables IDE click-to-navigate - For paths that could contain spaces, ensure they're quoted in the message ## Checklist for New Errors/Warnings - [ ] Error code assigned from correct `Strings.resx` range - [ ] "Next message code" comment updated in the resx - [ ] Message answers: what happened, why, what to do - [ ] `{StrBegin}` comment and placeholder documentation added - [ ] Severity chosen (error vs warning vs message) with WarnAsError considered - [ ] If warning: ChangeWave gating evaluated - [ ] Full build run to generate `.xlf` files - [ ] Test verifies the error is produced with correct code and text
GitHubで見る