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

  1. Fix the TargetName to exactly match an x:Name present in the same ControlTemplate/DataTemplate.
  2. Add or restore the named element the setter targets (give the target part x:Name="X").
  3. Remove the orphaned trigger/setter whose target no longer exists.
  4. 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

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


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)