dotnet/maui · error · InvalidOperationException

RootComponent requires a value for its ComponentType propert

Error message

RootComponent requires a value for its ComponentType property, but no value was set.

What it means

The WPF RootComponent.AddToWebViewManagerAsync validates ComponentType is non-null after validating Selector. Without a component type, the WebViewManager cannot instantiate a Razor component to render at the selector target. This is the second check in the pair — reaching it means Selector was already valid.

Source

Thrown at src/BlazorWebView/src/Wpf/RootComponent.cs:45

		/// <summary>
		/// Gets or sets an optional dictionary of parameters to pass to the root component.
		/// </summary>
		public IDictionary<string, object?>? Parameters { get; set; }

		internal Task AddToWebViewManagerAsync(WebViewManager webViewManager)
		{
			// As a characteristic of XAML,we can't rely on non-default constructors. So we have to
			// validate that the required properties were set. We could skip validating this and allow
			// the lower-level renderer code to throw, but that would be harder for developers to understand.

			if (string.IsNullOrWhiteSpace(Selector))
			{
				throw new InvalidOperationException($"{nameof(RootComponent)} requires a value for its {nameof(Selector)} property, but no value was set.");
			}

			if (ComponentType is null)
			{
				throw new InvalidOperationException($"{nameof(RootComponent)} requires a value for its {nameof(ComponentType)} property, but no value was set.");
			}

			var parameterView = Parameters == null ? ParameterView.Empty : ParameterView.FromDictionary(Parameters);
			return webViewManager.AddRootComponentAsync(ComponentType, Selector, parameterView);
		}

		internal Task RemoveFromWebViewManagerAsync(WebView2WebViewManager webviewManager)
		{
			return webviewManager.RemoveRootComponentAsync(Selector);
		}
	}
}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Set ComponentType to a type implementing IComponent: rc.ComponentType = typeof(MyComponent);
  2. In XAML, ensure the xmlns prefix is declared and correct: xmlns:local="clr-namespace:MyApp.Components" and ComponentType="{x:Type local:MyComponent}".
  3. Verify the assembly containing the component type is referenced and loaded.
  4. If using dynamic type resolution, add a null check and fallback: rc.ComponentType ?? throw new ConfigurationException("ComponentType must be set.");

Example fix

// before
var rc = new RootComponent { Selector = "#app" };
// after
var rc = new RootComponent { Selector = "#app", ComponentType = typeof(MyComponent) };
Defensive patterns

Strategy: validation

Validate before calling

// Validate ComponentType before adding
if (rootComponent.ComponentType is null)
{
    throw new InvalidOperationException("RootComponent.ComponentType must be set.");
}
await rootComponent.AddToWebViewManagerAsync(webViewManager);

Type guard

static bool HasComponentType(RootComponent rc)
{
    return rc?.ComponentType is not null && typeof(IComponent).IsAssignableFrom(rc.ComponentType);
}

Prevention

When it happens

Trigger: A RootComponent with a valid Selector but null ComponentType has AddToWebViewManagerAsync called. In XAML, this means the ComponentType binding or x:Type markup extension failed to resolve; in code, the property was never assigned.

Common situations: XAML ComponentType using {x:Type} that fails to resolve due to missing xmlns namespace declaration; dynamically created RootComponent where ComponentType was conditionally skipped; assembly containing the component type not loaded or renamed; refactor that changed the type's namespace without updating references.

Related errors


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