Skip to content

Project analysis fails ("No project found") unless TargetFramework is written literally in the test .csproj — an inherited or $(…)-referenced value is not seen #3758

Description

@PhilipThyregod

`

Describe the bug

Stryker's project analysis returns zero projects — and fails with No project found, check settings and ensure project file is not corrupted / Failed to analyze project builds. Stryker cannot continue. (exit 1) — whenever the test project's TargetFramework is not written literally in the .csproj file itself.

The property being in effect is not enough. In every failing case below the project restores, builds and tests normally, and dotnet msbuild <proj> -getProperty:TargetFramework prints net10.0 correctly. Only Stryker cannot see it.

Measured on a single fixture, changing one thing at a time, with a green dotnet build asserted immediately before every Stryker run:

where TargetFramework comes from | dotnet build | -getProperty:TargetFramework | Stryker -- | -- | -- | -- literal in the .csproj | ✅ | net10.0 | ✅ scores normally inherited from a parent-directory Directory.Build.props | ✅ | net10.0 | ❌ No project found a Directory.Build.props in the same directory as the .csproj | ✅ | net10.0 | ❌ No project found $(SliceTargetFramework) in the .csproj, value from Directory.Build.props | ✅ | net10.0 | ❌ No project found

The last two rows are the interesting ones:

  • it is not about import-chain depth — a props file sitting next to the project fails too;
  • and a property reference in the csproj fails where the identical literal succeeds, which suggests the project file is being inspected textually rather than evaluated.

That last row also rules out the natural workaround for repositories that centralise the framework version: you cannot keep a single source of truth in Directory.Build.props and reference it from the test project.

To reproduce

mkdir repro && cd repro

cat > Directory.Build.props <<'EOF'
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
</Project>
EOF

dotnet new classlib -n Lib -o Lib
dotnet new mstest -n Tests -o Tests
cd Tests && dotnet add reference ../Lib/Lib.csproj

Then remove the <TargetFramework> line from Tests/Tests.csproj so it is inherited from Directory.Build.props (add a mutable method + a test to Lib first so there is something to score).

dotnet build                      # succeeds
dotnet test # succeeds
dotnet msbuild Tests.csproj -getProperty:TargetFramework # prints net10.0
dotnet-stryker -p <abs path>/Lib/Lib.csproj -r Json --skip-version-check

 Analyzing 1 test project(s).  No project found ... → exit 1.

Put <TargetFramework>net10.0</TargetFramework> back into Tests.csproj, change nothing else, and the identical command scores normally.

Logs

-L produces no analyzer detail — this is the complete relevant portion at -L -V trace, and --diag adds nothing further:

[DBG] Analyzing "Tests.csproj"
[VRB] No analyzer results to log. This indicates an early failure in analysis, check log file for details.
[DBG] Analysis of project "Tests.csproj" succeeded.
[DBG] Analyzing 0 projects.
[WRN] No project found, check settings and ensure project file is not corrupted.

Two observations about this output, offered as diagnosability feedback rather than as the bug:

  • Analysis of project "Tests.csproj" succeeded. is logged even though the analysis produced zero results and the run is about to abort.
  • check log file for details points at a log that contains no such details. The underlying MSBuild/analyzer failure is discarded, which makes this class of problem very hard to diagnose — the same No project found is also what you get when the test project simply fails to build, or when a referenced project fails to restore, so three unrelated causes are indistinguishable from the output.

A note on instrumentation, in case it saves someone time: setting MSBUILDDEBUGENGINE=1 to capture a binlog changes the outcome — a fixture that otherwise scores fine then fails with this same error, and the captured binlog shows an SDK-resolution failure against a Visual Studio MSBuild directory that is not what the uninstrumented run does. So binlog capture is not a safe probe for this.

Expected behavior

TargetFramework should be picked up however MSBuild resolves it — from Directory.Build.props, from a property reference, or from any other import — since the project is otherwise perfectly buildable and testable. Failing that, the error should name the missing/unresolved property instead of the generic No project found.

Desktop (please complete the following information):

  • OS: Windows 11 Pro 26200
  • Type of project: core (SDK-style, net10.0)
  • Framework Version: .NET 10 (SDK 10.0.302); MSTest 4.0.2
  • Stryker Version: 4.16.0 (global tool)

Additional context

Ruled out as causes, each tested individually against a green baseline: Microsoft.NET.Sdk.Web and Microsoft.NET.Sdk.Razor project references; .slnx vs no solution file; Central Package Management (with and without transitive pinning); global.json SDK pinning; a solution-local NuGet.Config that clears inherited sources; TreatWarningsAsErrors + EnforceCodeStyleInBuild; IsPackable/IsTestProject; a large test package set (coverlet.collector, Shouldly, NSubstitute, bUnit, NetArchTest.Rules); and multiple project references. With a literal TargetFramework all of those combinations analyze fine.

Also tested and ineffective as workarounds: --target-framework net10.0, -tp <test csproj>, both together, and --msbuild-path pointed at the SDK's own MSBuild. There appears to be no CLI-side way to compensate, which is awkward for tooling that invokes Stryker against repositories it does not own.

Impact for context: in a monorepo that centralises TargetFramework in per-slice Directory.Build.props — a common convention — every test project is affected, and the only remedy is to duplicate the literal into each .csproj and guard against it drifting out of step.

`

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions