dotnet/maui · error · BuildException

XC0125

XC0125

Error message

"A resource with the key "{0}" is already present in the ResourceDictionary.

What it means

Raised by the XAML compiler (Build.Tasks) when two resources inside the same ResourceDictionary declare the same x:Key. The build task keeps a name set via GetResourceNamesInUse(parent) and rejects any key that already appears in it, so the XAML cannot compile until the collision is removed.

Solutions

  1. Search the whole XAML file (and any MergedDictionaries) for the duplicate x:Key and rename one of the two occurrences to a unique value.
  2. If the duplicate comes from a merged dictionary, override it intentionally with MergedWith/Source semantics or remove it from the source dictionary instead of redeclaring.
  3. Use a unique prefix per feature area (e.g. 'LoginPrimaryButton') to avoid accidental collisions as dictionaries grow.

Example fix

<!-- before -->
<ResourceDictionary>
    <x:String x:Key="Greeting">Hello</x:String>
    <x:String x:Key="Greeting">Hi</x:String>
</ResourceDictionary>
<!-- after -->
<ResourceDictionary>
    <x:String x:Key="Greeting">Hello</x:String>
    <x:String x:Key="GreetingAlt">Hi</x:String>
</ResourceDictionary>
Defensive patterns

Strategy: validation

Validate before calling

// Before shipping XAML, assert every x:Key in a ResourceDictionary is unique.
// Pseudo: gather all x:Key literal strings per RD scope and assert no duplicates.
static void AssertUniqueKeys(IEnumerable<string> keys)
{
    var dup = keys.GroupBy(k => k).Where(g => g.Count() > 1).Select(g => g.Key);
    if (dup.Any()) throw new InvalidOperationException("Duplicate keys: " + string.Join(", ", dup));
}

Prevention

When it happens

Trigger: The SetPropertiesVisitor sees a node whose parent collection is (or inherits from) Microsoft.Maui.Controls.ResourceDictionary, the node carries an x:Key whose string value is already present in context.Cache.GetResourceNamesInUse(parent), and the duplicate key throw fires.

Common situations: Copying a Style/Color/OnPlatform block and forgetting to rename its x:Key; merging MergedDictionaries that both define 'DefaultStyle'; refactoring resources between App.xaml and page-level dictionaries where the same key leaks in.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/df6faa13f515b9dd. Report an issue: GitHub.

Appendix: source

Thrown at src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs:1936

			return CanAddToResourceDictionary(parent, propertyType, elementNode, lineInfo, context);
		}

		static bool CanAddToResourceDictionary(VariableDefinition parent, TypeReference collectionType, ElementNode node, IXmlLineInfo lineInfo, ILContext context)
		{
			if (parent is null)
				return false;

			if (collectionType.FullName != "Microsoft.Maui.Controls.ResourceDictionary"
				&& !collectionType.InheritsFromOrImplements(context.Cache, context.Module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"))))
				return false;

			if (node.Properties.TryGetValue(XmlName.xKey, out INode value))
			{
				var valueNode = value as ValueNode ?? throw new BuildException(XKeyNotLiteral, lineInfo, null);
				var key = valueNode.Value as string;
				var names = context.Cache.GetResourceNamesInUse(parent);
				if (names.Contains(key))
					throw new BuildException(ResourceDictDuplicateKey, lineInfo, null, key);
				return true;
			}

			//is there a RD.Add() overrides that accepts this ?
			var nodeTypeRef = context.Variables[node].VariableType;
			var module = context.Body.Method.Module;
			if (module.ImportMethodReference(context.Cache,
											 module.GetTypeDefinition(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")),
											 methodName: "Add",
											 parameterTypes: [nodeTypeRef]) != null)
				return true;
			throw new BuildException(ResourceDictMissingKey, lineInfo, null);
		}

		static IEnumerable<Instruction> Add(VariableDefinition parent, XmlName propertyName, INode node, IXmlLineInfo iXmlLineInfo, ILContext context)
		{
			var module = context.Body.Method.Module;
			var elementNode = node as ElementNode;

View on GitHub (pinned to f377ff1c5e)