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
- Check if the component exists before removing: if (components.Any(c => c.Selector == selector)) components.Remove(selector);
- Maintain a reference to the RootComponent object and check before removing.
- Verify the selector string exactly matches what was used when adding (including case, since comparison is ordinal).
- 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
- Track added component selectors in a set and check membership before removing.
- Use ordinal string comparison awareness when matching selectors (case-sensitive).
- Avoid calling Remove in cleanup paths that may execute multiple times.
- Consider removing by index or object reference if available.
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
- 'selector' cannot be null or whitespace.
- RootComponent requires a value for its Selector property, bu
- RootComponent requires a value for its ComponentType propert
- RootComponent requires a value for its Selector property, bu
- RootComponent requires a value for its ComponentType propert
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/ed706a84708d2907.
Report an issue: GitHub.