AvaloniaUI/Avalonia · error · InvalidOperationException

NameScope is completed, no further registrations are allowed

Error message

NameScope is completed, no further registrations are allowed

What it means

Thrown by NameScope.Register when IsCompleted is true. A NameScope is 'completed' (sealed) after its owning template/control tree has been materialized — typically after ApplyTemplate finishes registering all named elements. Once sealed, no further name registrations are permitted because consumers (Find/Get) may already be resolving names against a frozen map.

Source

Thrown at src/Avalonia.Base/Controls/NameScope.cs:56

        }

        /// <summary>
        /// Sets the value of the attached <see cref="NameScopeProperty"/> on a styled element.
        /// </summary>
        /// <param name="styled">The styled element.</param>
        /// <param name="value">The value to set.</param>
        public static void SetNameScope(StyledElement styled, INameScope? value)
        {
            _ = styled ?? throw new ArgumentNullException(nameof(styled));

            styled.SetValue(NameScopeProperty, value);
        }

        /// <inheritdoc />
        public void Register(string name, object element)
        {
            if (IsCompleted)
                throw new InvalidOperationException("NameScope is completed, no further registrations are allowed");

            _ = name ?? throw new ArgumentNullException(nameof(name));
            _ = element ?? throw new ArgumentNullException(nameof(element));

            if (_inner.TryGetValue(name, out var existing))
            {
                if (existing != element)
                {
                    throw new ArgumentException($"Control with the name '{name}' already registered.");
                }
            }
            else
            {
                _inner.Add(name, element);
                if (_pendingSearches.Remove(name, out var tcs))
                {
                    tcs.SetResult(element);
                }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Register named elements before the NameScope is completed — during template construction / initial child setup, not after ApplyTemplate.
  2. If you need a new named element after load, create a fresh NameScope (or set a new NameScope on the element) rather than mutating the sealed one.
  3. Check nameScope.IsCompleted before calling Register and route to a new scope when true.

Example fix

// before
scope.Register("myItem", control); // throws if completed
// after
if (scope.IsCompleted)
    NameScope.SetNameScope(host, new NameScope());
NameScope.GetNameScope(host).Register("myItem", control);
Defensive patterns

Strategy: validation

Validate before calling

if (!nameScope.IsCompleted)
    nameScope.Register(name, element);

Try / catch

try { nameScope.Register(name, element); }
catch (InvalidOperationException ex) when (ex.Message.Contains("completed"))
{
    // create/use a fresh NameScope instead
}

Prevention

When it happens

Trigger: Calling nameScope.Register(name, element) on a NameScope whose IsCompleted flag has been set to true, which happens after the visual tree template is fully loaded and the scope is committed.

Common situations: Attempting to register a control into a NameScope after the template has been applied — e.g., dynamically adding a named child to a templated parent and trying to register it in the existing scope. Custom INameScope implementations that don't track completion correctly. Calling Register during a late-loaded content swap.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/c563c4dd96e07ff3. Report an issue: GitHub.