AvaloniaUI/Avalonia · error · InvalidOperationException

The ResourceDictionary already has a parent.

Error message

The ResourceDictionary already has a parent.

What it means

Thrown by ResourceProvider.AddOwner (explicit IResourceProvider implementation) when the ResourceDictionary already has an Owner assigned. A resource provider is single-owner: it can be attached to exactly one IResourceHost. Attempting to add it to a second host without first removing the previous owner is rejected.

Source

Thrown at src/Avalonia.Base/Controls/ResourceProvider.cs:83

    /// Handles when owner was removed.
    /// Base method implementation raises <see cref="IResourceHost.NotifyHostedResourcesChanged"/>, if this provider has any resources.
    /// </summary>
    /// <param name="owner">Old owner.</param>
    protected virtual void OnRemoveOwner(IResourceHost owner)
    {
        if (HasResources)
        {
            owner.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Create());
        }
    }

    void IResourceProvider.AddOwner(IResourceHost owner)
    {
        owner = owner ?? throw new ArgumentNullException(nameof(owner));

        if (Owner != null)
        {
            throw new InvalidOperationException("The ResourceDictionary already has a parent.");
        }

        Owner = owner;

        OnAddOwner(owner);
    }

    void IResourceProvider.RemoveOwner(IResourceHost owner)
    {
        owner = owner ?? throw new ArgumentNullException(nameof(owner));

        if (Owner == owner)
        {
            Owner = null;

            OnRemoveOwner(owner);
        }
    }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Call IResourceProvider.RemoveOwner(currentOwner) before adding the resource provider to a new owner.
  2. Create a separate ResourceDictionary instance per host rather than sharing one.
  3. If sharing read-only resources, clone or wrap them so each host owns its own provider.

Example fix

// before
provider.AddOwner(hostA);
provider.AddOwner(hostB); // throws — already owned
// after
provider.RemoveOwner(hostA);
provider.AddOwner(hostB);
Defensive patterns

Strategy: validation

Validate before calling

if (provider is IResourceProvider rp)
{
    // detach from previous owner first (check via reflection or known owner)
    if (CurrentOwner != null) rp.RemoveOwner(CurrentOwner);
    rp.AddOwner(newOwner);
}

Try / catch

try { ((IResourceProvider)provider).AddOwner(newOwner); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already has a parent"))
{ /* call RemoveOwner on the current owner first, then retry */ }

Prevention

When it happens

Trigger: Calling IResourceProvider.AddOwner(hostB) when Owner is already hostA (non-null). Happens when the same ResourceDictionary/ResourceProvider instance is shared across two controls/styles without being removed from the first.

Common situations: A single ResourceDictionary static instance is assigned to multiple Style.ResourceDictionaries or controls. Reusing a cached ResourceProvider across multiple windows without detaching. Programmatic ownership transfer that forgets RemoveOwner before AddOwner.

Related errors


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