Repository navigation
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Non-blocking follow-up to this review comment on #20574.
TemplateRestorePlan.Normalize in tools/GenerateTemplateManifest/TemplateRestorePlan.cs sorts unconditional ItemGroup children to canonicalize restore graphs. These rendered projects have not yet been evaluated by MSBuild, so sorting can change the meaning of order-sensitive item expressions.
For example:
<ItemGroup>
<TemplatePackage Include="System.CommandLine" Version="2.0.12" />
<PackageReference Include="@(TemplatePackage)" />
</ItemGroup>Sorting moves PackageReference before TemplatePackage. The reviewer reports that an MSBuild/restore probe restored System.CommandLine/2.0.12 from the original project, while the normalized project restored successfully with no libraries or dependencies. The resulting manifest would silently omit the package.
No current template uses an @(...) item expression, so this is not evidence that the current manifest is incomplete. This issue should not block #20574.
Expected Behavior
Normalization should preserve ItemGroup document order, including order across combined groups, so evaluating the generated project selects the same dependencies as evaluating the original.
Prefer preserving item order rather than attempting to recognize every order-sensitive expression. Possible approaches include canonicalizing only safe PropertyGroup shapes, or combining item groups without sorting their children.
Add an MSBuild-evaluation/restore regression test that proves the package in the example remains present after normalization. Confirm that existing template graph deduplication and manifest output remain correct.
Steps To Reproduce
- Create a minimal SDK-style project targeting a supported framework and containing the
ItemGroupabove. - Evaluate/restore the original project and record its package references and
project.assets.jsonlibraries. - Pass the project XML through
TemplateRestorePlan.Normalize, save the normalized project in an isolated directory, and evaluate/restore it. - Compare the results. As reported in the linked review, sorting places the item consumer before its declaration, omitting
System.CommandLinewithout causing restore to fail.
Exceptions (if any)
None reported: restore succeeds with the dependency missing.
Aspire doctor output
N/A — build-time template manifest normalization.
Anything else?
The reviewer also reports that removing ItemGroup sorting did not change the current plan size: 138 configurations / 518 project instances → 78 unique projects / 105 framework graphs. Recheck this when implementing the fix; preserving order may have no deduplication cost for today's templates.
Related: #20451. The existing guard against moving groups across top-level Choose/Import/Target elements addresses a different evaluation-order issue; this follow-up concerns sorting the item declarations themselves.
Activity
joperezr commentedon Sep 30, 2026
🤖 Aspire triage pass — 2026-09-30 22:43 UTC
Area:
area-engineering-systemsKind: bug
Repro: yes-minimal — see lines 13–20 and 32–37 of the issue body
Affected version(s): unreleased main after #20574 (latest: 13.6.0)
Severity: S3 — normalization can silently omit a dependency, but no current template uses the affected item-expression shape
Urgency: ⚪ backlog — no milestone
Reason: valid and actionable follow-up, but there is no demonstrated impact to current templates or a released Aspire version
Suggested owner(s): Ankit Jain (@radical) (score 55)
Evidence:
area-engineering-systems(last 7d)area-engineering-systemsConfidence: high
Needs human?: no
Preserve ItemGroup evaluation order in template manifest normalization (