Skip to content

Fix template load failure when template.json contains duplicate JSON property keys#10048

Closed
Copilot wants to merge 2 commits intomainfrom
copilot/fix-template-loading-error
Closed

Fix template load failure when template.json contains duplicate JSON property keys#10048
Copilot wants to merge 2 commits intomainfrom
copilot/fix-template-loading-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 25, 2026

Problem

Templates (notably MAUI) fail to load with ArgumentException: An item with the same key has already been added. Key: empty on .NET 10+ SDKs. The MAUI template.json has duplicate "empty" keys in the "forms" section. In .NET 10+, JsonObject switched to OrderedDictionary<TKey,TValue> with lazy initialization — JsonObject.Count triggers InitializeDictionary(), which throws on duplicates. JExtensions.PropertiesOf() called jObj.ToList(), and List<T>(ICollection<T>) calls Count to pre-size the list, hitting this path.

Solution

  • src/Shared/JExtensions.cs: Replace the bare jObj.ToList() calls in PropertiesOf() with a GetObjectProperties() helper that catches ArgumentException and falls back to GetObjectPropertiesViaDocument(). The fallback serializes via JsonObject.ToJsonString() (safe because WriteTo() uses the underlying JsonElement when _dictionary is null, even after a failed init) and re-enumerates with JsonDocument which tolerates duplicate keys.
// Before
return element is not JsonObject jObj ? [] : jObj.ToList(); // throws on duplicate keys

// After
return element is not JsonObject jObj ? [] : GetObjectProperties(jObj); // handles duplicates gracefully
  • test/.../TemplateConfigTests/GenericTests.cs: Two regression tests covering duplicate keys in "forms" and "symbols" sections.

Checks:

  • Added unit tests
Original prompt

This section details on the original issue you should resolve

<issue_title>[NETSDKE2E][Regression]Error: Failed to load template from "C:\xxx\microsoft.maui.templates.net10.10.0.20.nupkg(/content/templates/maui-blazor-solution/.template.config/template.json)" displays when running command in CLI for the first time.</issue_title>
<issue_description>RGRESSION INFO
not repro on VS 18.6 Insiders [11617.261.main] + 11.0.100-preview.3.26166.111 (runtime- 11.0.0-preview.3.26166.111)
not repro in CLI when only installed Insiders VS 18.6 [11618.325.main]

INSTALL STEPS

Insiders VS 18.6 [11618.325.main] + 11.0.100-preview.3.26168.106 (runtime- 11.0.100-preview.3.26168.106) on win-x64

REPRO STEPS
1.In CLI, run the dotnet command for the first time, e.g dotnet new sln

ACTUAL
sln is created successfully,but below error happens
Image
Error: Failed to load template from "C:\Program Files\dotnet\template-packs\microsoft.maui.templates.net10.10.0.20.nupkg(/content/templates/maui-blazor-solution/.template.config/template.json)".
Details: System.ArgumentException: An item with the same key has already been added. Key: empty (Parameter 'key')
at System.Collections.ThrowHelper.ThrowDuplicateKey[TKey](TKey key)
at System.Collections.Generic.OrderedDictionary2.TryInsert(Int32 index, TKey key, TValue value, InsertionBehavior behavior, Int32& keyIndex) at System.Collections.Generic.OrderedDictionary2.Add(TKey key, TValue value)
at System.Text.Json.Nodes.JsonObject.InitializeDictionary()
at System.Text.Json.Nodes.JsonObject.get_Count()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel.TemplateConfigModel..ctor(JsonObject source, ILogger logger, String baselineName) at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.DirectoryBasedTemplate..ctor(IEngineEnvironmentSettings settings, IGenerator generator, IFile templateFile, String baselineName) at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.RunnableProjectGenerator.GetTemplatesFromMountPointInternalAsync(IMountPoint source, CancellationToken cancellationToken) Error: Failed to load template from "C:\Program Files\dotnet\template-packs\microsoft.maui.templates.net10.10.0.20.nupkg(/content/templates/maui-blazor/.template.config/template.json)". Details: System.ArgumentException: An item with the same key has already been added. Key: empty (Parameter 'key') at System.Collections.ThrowHelper.ThrowDuplicateKey[TKey](TKey key) at System.Collections.Generic.OrderedDictionary2.TryInsert(Int32 index, TKey key, TValue value, InsertionBehavior behavior, Int32& keyIndex)
at System.Collections.Generic.OrderedDictionary2.Add(TKey key, TValue value) at System.Text.Json.Nodes.JsonObject.InitializeDictionary() at System.Text.Json.Nodes.JsonObject.get_Count() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel.TemplateConfigModel..ctor(JsonObject source, ILogger logger, String baselineName)
at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.DirectoryBasedTemplate..ctor(IEngineEnvironmentSettings settings, IGenerator generator, IFile templateFile, String baselineName)
at Microsoft.TemplateEngine.Orchestrator.RunnableProjects.RunnableProjectGenerator.GetTemplatesFromMountPointInternalAsync(IMountPoint source, CancellationToken cancellationToken)

Expected Result:
sln is created successfully without any erros

Note:
1.We don't meet it in CLI when only installing SDK
2.it not happens when running command in CLI for the second time</issue_description>

<agent_instructions>Can you review the code and determine if this is something hte template engine should fix or something in the authoring of the maui templates? From the description, it looks like an issue if you install a newer sdk and older SDK SxS and the new SDK finds a duplicate template between the new and old SDKS.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@balachir @marcpopMSFT is this an issue in the .NET SDK that needs to be looked at for .NET 11 P3? From [Nicole's scenario above](https://github.com//issues/10047#issuecomment-4128056053), this reproduces when only .NET SDK is installed and even the install of VS is not necessary. @marcpopMSFT Moving to templating because that's where the callstack is from.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

In .NET 10+, JsonObject.InitializeDictionary() throws ArgumentException
when duplicate property keys exist in JSON. The PropertiesOf() method
called .ToList() on JsonObject which triggered Count -> InitializeDictionary()
via the List<T>(ICollection<T>) constructor.

Fix: wrap the ToList() call in a try/catch for ArgumentException and
fall back to JsonDocument-based enumeration which tolerates duplicate keys.
JsonObject.WriteTo() safely returns the original JSON via its underlying
JsonElement even after a failed initialization.

Fixes: MAUI templates failing to load with 'An item with the same key
has already been added. Key: empty' error.

Co-authored-by: marcpopMSFT <12663534+marcpopMSFT@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/templating/sessions/71aa8b90-cc61-4d4e-92eb-2c3c821d5d5c
Copilot AI changed the title [WIP] Fix error loading template from nupkg file in CLI Fix template load failure when template.json contains duplicate JSON property keys Mar 25, 2026
Copilot AI requested a review from marcpopMSFT March 25, 2026 17:07
@marcpopMSFT
Copy link
Copy Markdown
Member

The original issue was a case collision to we'll prefer https://github.com/dotnet/templating/pull/10049/changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants