Msbuild: MSB4096 seems too strict: A Include="@(B)" C="%(D)" requires all existing A to have metadata D

Created on 3 Sep 2020  路  2Comments  路  Source: dotnet/msbuild

Issue Description

I think I'm getting MSB4096 in this situation even though in this context, it isn't a problem. Repro build.proj that gets MSB4096:

<Project>
  <Target Name="Build">
    <ItemGroup>
      <PackageReference Include="Foo" Version="1.0.0" />
      <Other Include="Other" ExactVersion="1.0.0" />
      <PackageReference Include="@(Other)" Version="[%(ExactVersion)]" /> <!-- MSB4096: must be Other.ExactVersion -->
    </ItemGroup>
  </Target>
</Project>

MSB4096's message is actionable and the workaround is easy, but it doesn't seem necessary based on my understanding of MSBuild, and I want to make sure I'm not missing some situation where the Version metadata actually has the potential to get replaced in a way I don't expect.

(I expect to be called out on this in a code review: my diff changes ExactVersion to Other.ExactVersion for no obvious reason. 馃槃 My PR goes from not having any pre-existing PackageReferences to adding Foo, causing MSB4096. Then I have to replace ExactVersion with Other.ExactVersion to fix that--this ends up being spooky action at a distance, and hard to review.)

Steps to Reproduce

With above repro project:

$ dotnet msbuild /bl

Expected Behavior

Success

Actual Behavior

error MSB4096: The item "Foo" in item list "PackageReference" does not define a value for
metadata "ExactVersion".  In order to use this metadata, either qualify it by specifying
%(PackageReference.ExactVersion), or ensure that all items in this list define a value for
this metadata.

Workaround

Replace the last item list line with <PackageReference Include="@(Other)" Version="[%(Other.ExactVersion)]" />.

Versions & Configurations

$ dotnet msbuild /version
Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

16.7.0.36003

Attach a binlog

metadata-must-exist-even-if-unused.zip

Language Needs Design bug

All 2 comments

Team Triage:
image
So, if the metadata exists on PackageReference then it is used from Other. That doesn't make sense. It does seem like we can just remove the warning, but we need to think that through.

Interesting experiment! I actually expected the result you got with my current mental model of MSBuild--the %(ExactVersion) always being "linked" to @(Other). But I see how it's confusing vs. the behavior of:
<PackageReference Version="[%(ExactVersion)]" />
The root issue as I see it is that there are two types of "implicit this", and they're colliding here in an awkward way. I'm not sure if there's some MSBuild precedent for which behavior to expect here--both sound fine to me. I haven't seen much in the docs about these kinds of item metadata batching anyway.

Was this page helpful?
0 / 5 - 0 ratings