Design-time build (DesignTimeBuild=true) fails with NETSDK1022 duplicate Compile ('.g.cs') in the _wpftmp project on .NET 10 SDK when XAML references a same-project type
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Description
On the .NET 10 SDK, running MSBuild with `-p:DesignTimeBuild=true` on a WPF project whose XAML references a **same-project type** fails with:
```
Microsoft.NET.Sdk.DefaultItems.Shared.targets(190,5): error NETSDK1022: Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default. ... The duplicate items were: '...\obj\Debug\net8.0-windows\LocalControl.g.cs'; '...\obj\Debug\net8.0-windows\GeneratedInternalTypeHelper.g.cs' [...\WpfLib_xxxxx_wpftmp.csproj]
```
The error is raised from the **temporary markup-compile project** (`*_wpftmp.csproj`, i.e. the `GenerateTemporaryTargetAssembly` pass) — the generated `.g.cs` files end up in its `Compile` items twice. The same command succeeds on the .NET 8 SDK, succeeds on the 10 SDK without the property, and a normal (non-design-time) build succeeds on both.
This breaks design-time analysis tooling generally: I hit it via Stryker.NET/Buildalyzer, whose project analysis performs an instrumented design-time build (see stryker-mutator/stryker-net#3701 for the investigation trail).
### Reproduction Steps
`WpfLib/WpfLib.csproj`:
```xml
net8.0-windows
true
```
`WpfLib/MyConverter.cs`:
```csharp
using System; using System.Globalization; using System.Windows.Data;
namespace WpfLib
{
public class MyConverter : IValueConverter
{
public object Convert(object v, Type t, object p, CultureInfo c) => v;
public object ConvertBack(object v, Type t, object p, CultureInfo c) => v;
}
}
```
`WpfLib/LocalControl.xaml` (the key part — it references the local type, which triggers the temp-assembly pass):
```xml
```
`WpfLib/LocalControl.xaml.cs`:
```csharp
using System.Windows.Controls;
namespace WpfLib { public partial class LocalControl : UserControl { public LocalControl() { InitializeComponent(); } } }
```
Then:
```
dotnet msbuild WpfLib\WpfLib.csproj /restore /t:Clean;Build -p:DesignTimeBuild=true
```
### Expected behavior
The design-time build succeeds (as it does on the .NET 8 SDK), or at least does not double-include the WPF-generated `.g.cs` files in the temporary project.
### Actual behavior
`error NETSDK1022: Duplicate 'Compile' items` for `LocalControl.g.cs` and `GeneratedInternalTypeHelper.g.cs`, raised in `WpfLib_*_wpftmp.csproj`; exit code 1.
### Regression?
Yes. The identical project and command succeed on SDK 8.0.420; they fail on SDK 10.0.301.
Additional data points:
- Only reproduces when the XAML references a **local (same-project) type** — with only package/framework xmlns references (no temp-assembly pass), the design-time build succeeds.
- `DesignTimeBuild=true` alone is sufficient; I bisected the full property set a design-time analyzer (Buildalyzer) passes, one property at a time, and every other property is innocent.
- `DefaultItemExcludes` in the failing build correctly contains `obj\**` for the real project; the duplication happens in the temp project's context.
### Known Workarounds
Pin the .NET 8 SDK via `global.json` for the analysis run, or avoid the design-time property set (a normal build is unaffected).
### Impact
Any tool that performs design-time builds of WPF projects (Buildalyzer, Stryker.NET, and similar analyzers) fails on .NET 10 SDK for projects with local-type XAML references.
Contributor guide
Research direction
Reproduce with WpfLib/WpfLib.csproj, LocalControl.xaml, and the provided MSBuild command using .NET 10, then inspect the generated WpfLib_*_wpftmp.csproj during the GenerateTemporaryTargetAssembly pass. Compare its Compile items with the successful .NET 8 run and confirm that the design-time build completes without duplicate LocalControl.g.cs or GeneratedInternalTypeHelper.g.cs entries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100