Skip to content

Fix unhandled exception in /getItem and /getTargetResult for items with illegal path characters#12841

Merged
JanProvaznik merged 6 commits intomainfrom
copilot/fix-unhandled-exception-getcompilecommands
Jan 5, 2026
Merged

Fix unhandled exception in /getItem and /getTargetResult for items with illegal path characters#12841
JanProvaznik merged 6 commits intomainfrom
copilot/fix-unhandled-exception-getcompilecommands

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 27, 2025

Context

/getItem and /getTargetResult throw an unhandled InvalidOperationException when serializing items whose item specs contain illegal path characters (e.g., compiler command line flags from ClangTidy's GetCompileCommands target).

The JSON output formatter iterates over all metadata names including built-in metadata like FullPath, Directory, etc. When GetMetadata() is called on these, it attempts path computation which fails for non-path item specs.

Changes Made

  • Wrapped metadata retrieval in JsonOutputFormatter.cs with try-catch for InvalidOperationException
  • Added TryGetMetadata and TryGetMetadataValue helper methods that return empty string on failure
  • Applied fix to all three affected methods: AddTargetResultsInJsonFormat, AddItemInstancesInJsonFormat, AddItemsInJsonFormat
  • Exception handling catches all InvalidOperationException instances to ensure compatibility across all locales (error messages are localized)

Testing

Added GetTargetResultWithIllegalPathCharacters test that verifies both /getTargetResult and /getItem succeed with items containing compiler flags as item specs.

Notes

On Linux, the test shows the path-like metadata is still computed (since / is valid in paths). On Windows, these would return empty strings. The key fix is preventing the unhandled exception crash.

The exception handling is intentionally broad (catching all InvalidOperationException without message filtering) to ensure the fix works correctly in all locales, as error messages from MSBuild are localized and checking for specific English text would fail in non-English environments.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Unhandled Exception]: /getItem and /getTargetResult fail for target GetCompileCommands</issue_title>
<issue_description>### Issue Description

There is an uncaught exception when trying to access certain information from the GetCompileCommands target (from ClangTidy), in particular /getTargetResult:GetCompileCommands and /getTargetResult:GetCompileCommands

Steps to Reproduce

tidytest.zip

Run either of the following commands (You could also run with target /t:ClangTidy for the same result)

msbuild tidytest.vcxproj /t:GetCompileCommands /getTargetResult:GetCompileCommands
msbuild tidytest.vcxproj /t:GetCompileCommands /getItem:CompileCommands

I expect to get a json formatted target result or item.

Actual Behavior

I get the following error when building

C:\Users\rp0656\source\repos\tidytest>msbuild tidytest.vcxproj /t:GetCompileCommands /getTargetResult:GetCompileCommands
MSBUILD : error MSB1025: An internal failure occurred while running MSBuild.
System.InvalidOperationException: The item metadata "%(FullPath)" cannot be applied to the path "/c /nologo /W3 /WX- /diagnostics:column /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Fa"tidytest\x64\Debug\\" /Fo"tidytest\x64\Debug\\" /Gd --target=amd64-pc-windows-msvc   /TP". Illegal characters in path.
   at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args)
   at Microsoft.Build.Shared.FileUtilities.ItemSpecModifiers.GetItemSpecModifier(String currentDirectory, String itemSpec, String definingProjectEscaped, String modifier, String& fullPath)
   at Microsoft.Build.Evaluation.BuiltInMetadata.GetMetadataValueEscaped(String currentDirectory, String evaluatedIncludeBeforeWildcardExpansionEscaped, String evaluatedIncludeEscaped, String definingProjectEscaped, String name, String& fullPath)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetBuiltInMetadataEscaped(String name)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetMetadataEscaped(String metadataName)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetMetadata(String metadataName)
   at Microsoft.Build.CommandLine.JsonOutputFormatter.AddTargetResultsInJsonFormat(String[] targetNames, BuildResult result)
   at Microsoft.Build.CommandLine.MSBuildApp.OutputBuildInformationInJson(BuildResult result, String[] getProperty, String[] getItem, String[] getTargetResult, ILogger[] loggers, ExitType exitType, TextWriter outputStream)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String commandLine)

Unhandled Exception: System.InvalidOperationException: The item metadata "%(FullPath)" cannot be applied to the path "/c /nologo /W3 /WX- /diagnostics:column /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Fa"tidytest\x64\Debug\\" /Fo"tidytest\x64\Debug\\" /Gd --target=amd64-pc-windows-msvc   /TP". Illegal characters in path.
   at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args)
   at Microsoft.Build.Shared.FileUtilities.ItemSpecModifiers.GetItemSpecModifier(String currentDirectory, String itemSpec, String definingProjectEscaped, String modifier, String& fullPath)
   at Microsoft.Build.Evaluation.BuiltInMetadata.GetMetadataValueEscaped(String currentDirectory, String evaluatedIncludeBeforeWildcardExpansionEscaped, String evaluatedIncludeEscaped, String definingProjectEscaped, String name, String& fullPath)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetBuiltInMetadataEscaped(String name)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetMetadataEscaped(String metadataName)
   at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.GetMetadata(String metadataName)
   at Microsoft.Build.CommandLine.JsonOutputFormatter.AddTargetResultsInJsonFormat(String[] targetNames, BuildResult result)
   at Microsoft.Build.CommandLine.MSBuildApp.OutputBuildInformationInJson(BuildResult result, String[] getProperty, String[] getItem, String[] getTargetResult, ILogger[] loggers, ExitType exitType, TextWriter outputStream)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String commandLine)
   at Microsoft.Build.CommandLine.MSBuildApp.Main()

Analysis

The error suggests that it is trying to interpret the flags of the compile commands as a path, which causes an error when it can't be resolved. The function %(FullPath) is used, though it is not clear to me exactly where, but my best guess is it used on a variable that is supposed to just be the path to cl, but has been extended with flags.

See the clang tidy targets file at something similar to C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.Cpp.ClangTidy.targets

Versions & Co...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits November 27, 2025 14:04
…egal path characters

Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
…ilt-in modifier'

Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unhandled exception for GetCompileCommands target Fix unhandled exception in /getItem and /getTargetResult for items with illegal path characters Nov 27, 2025
Copilot AI requested a review from JanProvaznik November 27, 2025 14:12
@JanProvaznik
Copy link
Copy Markdown
Member

JanProvaznik commented Nov 27, 2025

PS C:\Users\janprovaznik\Downloads\tidytest> D:\msbuilds\msb9\artifacts\bin\bootstrap\net472\MSBuild\Current\Bin\amd64\MSBuild.exe tidytest.vcxproj /t:GetCompileCommands /getItem:CompileCommands
{
  "Items": {
    "CompileCommands": [
      {
        "Identity": "/c /nologo /W3 /WX- /diagnostics:column /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Fa\u0022tidytest\\Debug\\\\\u0022 /Fo\u0022tidytest\\Debug\\\\\u0022 /Gd --target=i686-pc-windows-msvc   /TP",
        "WorkingDirectory": "C:\\Users\\janprovaznik\\Downloads\\tidytest",
        "Files": "C:\\Users\\janprovaznik\\Downloads\\tidytest\\main.cpp",
        "ToolPath": "C:\\Windows\\system32\\CL.exe",
        "FullPath": "",
        "RootDir": "",
        "Filename": "",
        "Extension": "",
        "RelativeDir": "",
        "Directory": "",
        "RecursiveDir": "",
        "ModifiedTime": "",
        "CreatedTime": "",
        "AccessedTime": "",
        "DefiningProjectFullPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Microsoft\\VC\\v170\\Microsoft.Cpp.ClangTidy.targets",
        "DefiningProjectDirectory": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Microsoft\\VC\\v170\\",
        "DefiningProjectName": "Microsoft.Cpp.ClangTidy",
        "DefiningProjectExtension": ".targets"
      }
    ]
  }
}
PS C:\Users\janprovaznik\Downloads\tidytest> D:\msbuilds\msb9\artifacts\bin\bootstrap\net472\MSBuild\Current\Bin\amd64\MSBuild.exe tidytest.vcxproj /t:GetCompileCommands /getTargetResult:GetCompileCommands
{
  "TargetResults": {
    "GetCompileCommands": {
      "Result": "Success",
      "Items": [
        {
          "Identity": "/c /nologo /W3 /WX- /diagnostics:column /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Fa\u0022tidytest\\Debug\\\\\u0022 /Fo\u0022tidytest\\Debug\\\\\u0022 /Gd --target=i686-pc-windows-msvc   /TP",
          "WorkingDirectory": "C:\\Users\\janprovaznik\\Downloads\\tidytest",
          "Files": "C:\\Users\\janprovaznik\\Downloads\\tidytest\\main.cpp",
          "ToolPath": "C:\\Windows\\system32\\CL.exe",
          "FullPath": "",
          "RootDir": "",
          "Filename": "",
          "Extension": "",
          "RelativeDir": "",
          "Directory": "",
          "RecursiveDir": "",
          "ModifiedTime": "",
          "CreatedTime": "",
          "AccessedTime": "",
          "DefiningProjectFullPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Microsoft\\VC\\v170\\Microsoft.Cpp.ClangTidy.targets",
          "DefiningProjectDirectory": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Microsoft\\VC\\v170\\",
          "DefiningProjectName": "Microsoft.Cpp.ClangTidy",
          "DefiningProjectExtension": ".targets"
        }
      ]
    }
  }
}

the command output from original issue makes sense

Copy link
Copy Markdown
Member

@JanProvaznik JanProvaznik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@JanProvaznik JanProvaznik marked this pull request as ready for review December 1, 2025 10:29
Copilot AI review requested due to automatic review settings December 1, 2025 10:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an unhandled exception that occurs when using /getItem or /getTargetResult with items whose specs contain illegal path characters, such as compiler command-line flags from ClangTidy's GetCompileCommands target.

Key Changes

  • Added exception handling for InvalidOperationException when retrieving metadata that requires path computation
  • Created three helper methods (TryGetMetadata and two TryGetMetadataValue overloads) to safely retrieve metadata
  • Added regression test to verify the fix works for both /getItem and /getTargetResult switches

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/MSBuild/JsonOutputFormatter.cs Added exception handling in metadata retrieval to prevent crashes when item specs contain illegal path characters; added three helper methods to safely get metadata values
src/MSBuild.UnitTests/XMake_Tests.cs Added regression test that verifies both /getItem and /getTargetResult work correctly with items containing compiler flags as item specs

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

@baronfel baronfel added the bug label Dec 15, 2025
Co-authored-by: YuliiaKovalova <95473390+YuliiaKovalova@users.noreply.github.com>
Co-authored-by: JanProvaznik <25267098+JanProvaznik@users.noreply.github.com>
Copilot AI requested a review from JanProvaznik January 5, 2026 12:58
@JanProvaznik JanProvaznik enabled auto-merge (squash) January 5, 2026 13:22
@JanProvaznik JanProvaznik merged commit 49a6fd4 into main Jan 5, 2026
10 checks passed
@JanProvaznik JanProvaznik deleted the copilot/fix-unhandled-exception-getcompilecommands branch January 5, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Unhandled Exception]: /getItem and /getTargetResult fail for target GetCompileCommands

5 participants