dotnet/wpf · error · ArgumentException
SR.KeyCollectionHasInvalidKey
Error message
SR.KeyCollectionHasInvalidKey
What it means
Thrown as ArgumentException from ResourceDictionary.SetKeys when a KeyRecord in the deferred-content key collection has neither a KeyString nor a valid type — i.e. the key is invalid. This is an internal invariant of the BAML deferred-content parser: every key record must carry a usable key.
Solutions
- Regenerate/recompile the BAML resource (rebuild the assembly)
- Ensure any custom XAML reader sets either KeyString or a valid key type on every KeyRecord
- Verify the assembly's .baml resources are not corrupted or tampered with
Defensive patterns
Strategy: validation
Validate before calling
foreach (var k in keyRecords) { if (k?.KeyString == null && k?.KeyType == null) throw new ArgumentException("Invalid key record"); } Try / catch
try { dict.DeferrableContent = content; } catch (ArgumentException ex) { /* log malformed BAML, rebuild resources */ } Prevention
- Rebuild assemblies if BAML corruption is suspected
- In custom XAML readers, always set KeyString or a valid key type on KeyRecord
When it happens
Trigger: Deferred BAML content whose key collection contains a KeyRecord with null KeyString and no recognized key type (e.g. corrupted or hand-built key records passed to SetKeys).
Common situations: Custom XAML reader implementations producing malformed key records; corrupted compiled BAML resources; rarely hit by ordinary application code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Can't Assign to Known Type attributes
- Could not find prefix for type
- Found unexpected Xmlns BAML record
- SR.ExpectedBamlSchemaContext
- SR.ExpectedResourceDictionaryTarget
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/23a92f3fbaf7fe81.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs:1296
if (keyRecord != null && keyRecord.HasStaticResources)
{
SetOptimizedStaticResources(keyRecord.StaticResources, serviceProvider, staticResourceWorker);
}
_baseDictionary.Add(value, keyRecord);
if (TraceResourceDictionary.IsEnabled)
{
TraceResourceDictionary.TraceActivityItem(
TraceResourceDictionary.SetKey,
this,
value);
}
}
else
{
throw new ArgumentException(SR.KeyCollectionHasInvalidKey);
}
}
// Notify owners of the HasImplicitStyles flag value
// but there is not need to fire an invalidation.
NotifyOwners(new ResourcesChangeInfo(null, this));
}
/// <summary>
/// Convert the OptimizedStaticResource and StaticResource items into StaticResourceHolders.
/// A StaticResourceHolder is derived from StaticResourceExtension and is a MarkupExtension.
/// The differences is that it contain a DeferredResourceReference as its "PrefetchedValue".
/// DeferredResourceReferences hold the dictionary and the key of the resource. It is a
/// way of looking up the reference now (for later use) but not expanding the entry.
/// Also the dictionary has a reference back to the Deferrred Reference. If dictionary entry
/// is modifed the DeferredResourceReference is told and it will grab the old value.
/// StaticResourceHolder is a MarkupExtension and thus can be returned as a "Value" in the Node Stream.
///View on GitHub (pinned to 81131a70a4)