dotnet/maui · error · ArgumentException

There is no root component with selector '{selector}'.

Error message

There is no root component with selector '{selector}'.

What it means

The RootComponentsCollection.Remove(string selector) extension method iterates all root components and removes the one whose Selector matches (ordinal comparison). If no component in the collection has that exact selector, it throws ArgumentException. This prevents silent no-ops when removing a component that was never added or was already removed.

Source

Thrown at src/BlazorWebView/src/WindowsForms/RootComponentCollectionExtensions.cs:46

		/// <summary>
		/// Removes the component associated with the specified <paramref name="selector"/> from the collection
		/// specified by <paramref name="components" /> .
		/// </summary>
		/// <param name="components">The collection from which the component associated with the selector should be removed.</param>
		/// <param name="selector">The selector associated with the component to be removed.</param>
		public static void Remove(this RootComponentsCollection components, string selector)
		{
			for (var i = 0; i < components.Count; i++)
			{
				if (components[i].Selector.Equals(selector, StringComparison.Ordinal))
				{
					components.RemoveAt(i);
					return;
				}
			}

			throw new ArgumentException($"There is no root component with selector '{selector}'.", nameof(selector));
		}
	}
}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Check if the component exists before removing: if (components.Any(c => c.Selector == selector)) components.Remove(selector);
  2. Maintain a reference to the RootComponent object and check before removing.
  3. Verify the selector string exactly matches what was used when adding (including case, since comparison is ordinal).
  4. Track removal state to avoid double-removal in cleanup paths.

Example fix

// before
components.Remove("#my-component"); // throws if not found
// after
if (components.Any(c => c.Selector.Equals("#my-component", StringComparison.Ordinal)))
{
    components.Remove("#my-component");
}
Defensive patterns

Strategy: validation

Validate before calling

// Check existence before removing
var existing = components.FirstOrDefault(c => c.Selector.Equals(selector, StringComparison.Ordinal));
if (existing is null)
{
    // Selector not found; skip or log
    return;
}
components.Remove(selector);

Type guard

static bool HasRootComponent(RootComponentsCollection components, string selector)
{
    return components.Any(c => c.Selector.Equals(selector, StringComparison.Ordinal));
}

Try / catch

try
{
    components.Remove(selector);
}
catch (ArgumentException)
{
    // Component was already removed or never existed; safe to ignore during cleanup
}

Prevention

When it happens

Trigger: Calling components.Remove("#my-component") when no RootComponent with Selector "#my-component" exists in the RootComponentsCollection. This includes cases where the selector was misspelled, the component was already removed, or was never added.

Common situations: Removing a component that was already removed in a previous call; typo in the selector string; case sensitivity mismatch (comparison is StringComparison.Ordinal, so '#App' != '#app'); removing by a selector that was dynamically generated and no longer matches; cleanup code that runs multiple times.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/ed706a84708d2907. Report an issue: GitHub.