{"record":{"id":"3d9932a2c8c48226","repo":"PrismLibrary/Prism","slug":"the-builder-does-not-implement-iregistryaware","errorCode":null,"errorMessage":"The builder does not implement IRegistryAware","messagePattern":"The builder does not implement IRegistryAware","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Navigation/Builder/NavigationBuilderExtensions.cs","lineNumber":24,"sourceCode":"\npublic static class NavigationBuilderExtensions\n{\n    /// <summary>\n    /// Creates a <see cref=\"INavigationBuilder\"/> using the current instance of the <see cref=\"INavigationService\"/>.\n    /// </summary>\n    /// <param name=\"navigationService\">The <see cref=\"INavigationService\"/>.</param>\n    /// <returns><see cref=\"INavigationBuilder\"/></returns>\n    public static INavigationBuilder CreateBuilder(this INavigationService navigationService) =>\n           new NavigationBuilder(navigationService);\n\n    internal static string GetNavigationKey<TViewModel>(object builder)\n    {\n        var vmType = typeof(TViewModel);\n        if (vmType.IsAssignableFrom(typeof(VisualElement)))\n            throw new NavigationException(NavigationException.MvvmPatternBreak, typeof(TViewModel).Name);\n\n        if (builder is not IRegistryAware registryAware)\n            throw new Exception(\"The builder does not implement IRegistryAware\");\n\n        return registryAware.Registry.GetViewModelNavigationKey(vmType);\n    }\n\n    public static INavigationBuilder RelativeBack(this INavigationBuilder builder) =>\n        builder.AddSegment(\"..\");\n\n    /// <summary>\n    /// This will force the generated Navigation URI to return an Absolute URI resetting the current <see cref=\"Window\"/>'s <see cref=\"Page\"/> property.\n    /// </summary>\n    /// <param name=\"builder\">The <see cref=\"INavigationBuilder\"/>.</param>\n    /// <returns>The <see cref=\"INavigationBuilder\"/>.</returns>\n    public static INavigationBuilder UseAbsoluteNavigation(this INavigationBuilder builder) =>\n        builder.UseAbsoluteNavigation(true);\n\n    /// <summary>\n    /// Adds the specified segment `ViewA` to the Navigation URI\n    /// </summary>","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Navigation/Builder/NavigationBuilderExtensions.cs#L6-L42","documentation":"GetNavigationKey requires the passed builder object to implement IRegistryAware so it can look up the ViewModel's navigation key in the view registry. If a custom/foreign INavigationBuilder implementation is passed that lacks the registry, Prism throws a plain Exception: 'The builder does not implement IRegistryAware'.","triggerScenarios":"Calling the generic NavigationBuilderExtensions (CreateBuilder<TViewModel> etc.) with a custom class implementing INavigationBuilder (or ICreateSegmentBuilder etc.) that does not also implement IRegistryAware.","commonSituations":"Custom navigation builder implementations written for testing or decoration; mock builders in unit tests passed into extension methods; library upgrades where the registry-aware interface was introduced and custom builders weren't updated.","solutions":["Make the custom builder implement IRegistryAware and expose the IViewRegistry (e.g. hold a reference to the app's registry).","Use Prism's built-in NavigationBuilder (from navigationService.CreateBuilder()) instead of a custom implementation.","In tests, replace the mock with a spy on INavigationService rather than a bespoke INavigationBuilder."],"exampleFix":"// before\nclass TestBuilder : INavigationBuilder { ... } // no IRegistryAware\n// after\nclass TestBuilder : INavigationBuilder, IRegistryAware\n{\n    public IViewRegistry Registry { get; }\n    public TestBuilder(IViewRegistry registry) => Registry = registry;\n    ...\n}","handlingStrategy":"type-guard","validationCode":"if (builder is not IRegistryAware)\n    throw new ArgumentException(\"Builder must implement IRegistryAware to resolve ViewModel navigation keys.\");","typeGuard":"INavigationBuilder EnsureRegistryAware(INavigationBuilder b) =>\n    b is IRegistryAware ? b : throw new ArgumentException(\"Builder is not IRegistryAware\");","tryCatchPattern":"try\n{\n    navigationService.CreateBuilder<MyViewModel>().NavigateAsync();\n}\ncatch (Exception ex) when (ex.Message.Contains(\"IRegistryAware\"))\n{\n    logger.LogError(ex, \"Custom builder lacks IRegistryAware; use Prism's built-in builder\");\n}","preventionTips":["Prefer Prism's factory-created builders (navigationService.CreateBuilder()) over hand-rolled INavigationBuilder implementations.","If writing a custom builder, always implement IRegistryAware from day one.","In tests, mock INavigationService rather than INavigationBuilder."],"tags":["navigation","builder","missing-interface"],"backgroundTag":"missing-dependency","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}