{"record":{"id":"2c18a339ef377d23","repo":"dotnet/maui","slug":"rootcomponent-requires-a-value-for-its-selector-pr","errorCode":null,"errorMessage":"RootComponent requires a value for its Selector property, but no value was set.","messagePattern":"RootComponent requires a value for its Selector property, but no value was set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BlazorWebView/src/Maui/RootComponent.cs","lineNumber":41,"sourceCode":"\t\t/// <summary>\n\t\t/// Gets or sets the type of the root component. This type must implement <see cref=\"IComponent\"/>.\n\t\t/// </summary>\n\t\tpublic Type? ComponentType { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets or sets an optional dictionary of parameters to pass to the root component.\n\t\t/// </summary>\n\t\tpublic IDictionary<string, object?>? Parameters { get; set; }\n\n\t\tinternal Task AddToWebViewManagerAsync(WebViewManager webViewManager)\n\t\t{\n\t\t\t// As a characteristic of XAML,we can't rely on non-default constructors. So we have to\n\t\t\t// validate that the required properties were set. We could skip validating this and allow\n\t\t\t// the lower-level renderer code to throw, but that would be harder for developers to understand.\n\n\t\t\tif (string.IsNullOrWhiteSpace(Selector))\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException($\"{nameof(RootComponent)} requires a value for its {nameof(Selector)} property, but no value was set.\");\n\t\t\t}\n\n\t\t\tif (ComponentType is null)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException($\"{nameof(RootComponent)} requires a value for its {nameof(ComponentType)} property, but no value was set.\");\n\t\t\t}\n\n\t\t\tvar parameterView = Parameters == null ? ParameterView.Empty : ParameterView.FromDictionary(Parameters);\n\t\t\treturn webViewManager.AddRootComponentAsync(ComponentType, Selector, parameterView);\n\t\t}\n\n\t\tinternal Task RemoveFromWebViewManagerAsync(WebViewManager webviewManager)\n\t\t{\n\t\t\tif (string.IsNullOrWhiteSpace(Selector))\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException($\"{nameof(RootComponent)} requires a value for its {nameof(Selector)} property, but no value was set.\");\n\t\t\t}\n\t\t\treturn webviewManager.RemoveRootComponentAsync(Selector);","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/BlazorWebView/src/Maui/RootComponent.cs#L23-L59","documentation":"The Maui RootComponent.AddToWebViewManagerAsync method validates that the Selector CSS property is non-empty before forwarding the request to WebViewManager.AddRootComponentAsync. Because XAML instantiates objects via parameterless constructors, required properties must be validated at call time rather than constructor time. A null or whitespace Selector means Blazor has no DOM target to render the component into.","triggerScenarios":"A RootComponent declared in XAML or code has its Selector property unset (null or whitespace string) and then AddToWebViewManagerAsync is called, either explicitly or when the BlazorWebView collects its RootComponents collection during startup.","commonSituations":"XAML RootComponent tag missing the Selector attribute; dynamically creating RootComponent objects in a loop and forgetting to set Selector on one; copy-paste error where Selector was renamed or removed; binding Selector to a property that evaluates to null at runtime.","solutions":["Set the Selector property on every RootComponent to a valid CSS selector string (e.g. '#app' or '.blazor-root').","In XAML, add the Selector attribute: <RootComponent Selector=\"#app\" ComponentType=\"{x:Type local:MyComponent}\" />.","If creating RootComponents dynamically, validate Selector before adding: if (!string.IsNullOrWhiteSpace(rc.Selector)) { ... }.","Audit all RootComponent declarations (XAML and code) to ensure none are missing Selector."],"exampleFix":"// before\nvar rc = new RootComponent\n{\n    ComponentType = typeof(MyComponent)\n};\n// after\nvar rc = new RootComponent\n{\n    Selector = \"#app\",\n    ComponentType = typeof(MyComponent)\n};","handlingStrategy":"validation","validationCode":"// Validate before adding to WebViewManager\nif (string.IsNullOrWhiteSpace(rootComponent.Selector))\n{\n    throw new InvalidOperationException(\"RootComponent.Selector must be set before adding.\");\n}\nawait rootComponent.AddToWebViewManagerAsync(webViewManager);","typeGuard":"static bool IsValidRootComponentSelector(RootComponent rc)\n{\n    return !string.IsNullOrWhiteSpace(rc?.Selector);\n}","tryCatchPattern":null,"preventionTips":["Set Selector in XAML attributes explicitly: <RootComponent Selector=\"#app\" ... />.","When creating RootComponent dynamically, always set Selector first.","Use a helper method that validates Selector and ComponentType before adding.","Add a code review checklist item for RootComponent property completeness."],"tags":["blazor","blazorwebview","maui","rootcomponent","validation","xaml"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}