dotnet/wpf · error · InvalidOperationException
SR.Format(SR.NameNotFound, propertyValue.ChildName)
Error message
SR.Format(SR.NameNotFound, propertyValue.ChildName)
What it means
Thrown by StyleHelper.UpdateTables when a template's SetterValueBindingHelper/PropertyValue (ChildValuePropertyEntry) references a child by ChildName that cannot be resolved within the template's child table. QueryChildIndexFromChildName returns -1 because the name is not registered in the template namescope/child name map, so WPF throws InvalidOperationException(NameNotFound).
Solutions
- Fix the TargetName to exactly match an x:Name present in the same ControlTemplate/DataTemplate.
- Add or restore the named element the setter targets (give the target part x:Name="X").
- Remove the orphaned trigger/setter whose target no longer exists.
- Search the template for all TargetName="..." references and diff them against the set of x:Name attributes to find dangling ones before applying.
Example fix
<!-- before -->
<ControlTemplate TargetType="Button">
<Border>
<ContentPresenter x:Name="Presenter"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HoverBorder" Property="Background" Value="LightBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- after (name matches an existing part) -->
<ControlTemplate TargetType="Button">
<Border x:Name="HoverBorder">
<ContentPresenter x:Name="Presenter"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HoverBorder" Property="Background" Value="LightBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate> Defensive patterns
Strategy: validation
Validate before calling
// Ensure every Trigger/Setters TargetName exists as an x:Name in the template
bool targetNamesResolve(ControlTemplate t) {
var named = new HashSet<string>();
CollectNames(t.VisualTree, named); // walk FrameworkElementFactory tree for x:Name values
return t.Triggers.Cast<TriggerBase>()
.SelectMany(tr => tr is MultiTrigger mt ? mt.Setters : tr.Setters.Cast<SetterBase>())
.OfType<Setter>().Where(s => s.TargetName != null)
.All(s => named.Contains(s.TargetName));
} Type guard
bool hasNamedPart(ControlTemplate t, string name) =>
t != null && t.VisualTree != null && FindNamedFactory(t.VisualTree, name) != null; Try / catch
try { element.ApplyTemplate(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("name") || ex.Message.Contains("Name"))
{
// diff TargetName references against x:Name parts, fix or remove the dangling setter
} Prevention
- After renaming/removing template parts, grep all TargetName attributes in the same template
- Keep triggers and the parts they target in the same template file to avoid drift
- Run a build-time XAML lint comparing TargetName references to x:Name declarations
- Prefer setting properties on the template root (TargetName omitted for container) when a named part is not truly needed
When it happens
Trigger: A template trigger or setter with TargetName="X" where X does not match any named element (x:Name/Name) in the template's visual tree — e.g. typo'd TargetName, the named element was removed/renamed, or TargetName points outside the template. Surfaces when the template's property value tables are updated (template seal/apply).
Common situations: Renaming or deleting a template part without updating trigger TargetName references; misspelled TargetName in XAML; styles shared across templates where one template lacks the referenced part; refactoring XAML that split templates and left dangling TargetNames.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- SR.ChildNameMustBeNonEmpty
- SR.Format(SR.CannotHavePropertyInTemplate…
- SR.Format(SR.NameScopeDuplicateNamesNotAllowed, childName)
- SR.Format(SR.NameScopeNotFound, name, "register")
- SR.Format(SR.NameScopeNotFound, name, "register")
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/781bd67d55bfd855.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/StyleHelper.cs:496
//
internal static void UpdateTables(
ref PropertyValue propertyValue,
ref FrugalStructList<ChildRecord> childRecordFromChildIndex,
ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex,
ref FrugalStructList<ChildPropertyDependent> resourceDependents,
ref HybridDictionary dataTriggerRecordFromBinding,
HybridDictionary childIndexFromChildName,
ref bool hasInstanceValues)
{
//
// Record instructions for Child/Self value computation
//
// Query for child index (may be 0 if "self")
int childIndex = QueryChildIndexFromChildName(propertyValue.ChildName, childIndexFromChildName);
if (childIndex == -1)
{
throw new InvalidOperationException(SR.Format(SR.NameNotFound, propertyValue.ChildName));
}
object value = propertyValue.ValueInternal;
bool requiresInstanceStorage = RequiresInstanceStorage(ref value);
propertyValue.ValueInternal = value;
childRecordFromChildIndex.EnsureIndex(childIndex);
ChildRecord childRecord = childRecordFromChildIndex[childIndex];
int mapIndex = childRecord.ValueLookupListFromProperty.EnsureEntry(propertyValue.Property.GlobalIndex);
ChildValueLookup valueLookup = new ChildValueLookup
{
LookupType = (ValueLookupType)propertyValue.ValueType, // Maps directly to ValueLookupType for applicable values
Conditions = propertyValue.Conditions,
Property = propertyValue.Property,
Value = propertyValue.ValueInternal
};View on GitHub (pinned to 81131a70a4)