PrismLibrary/Prism · error · InvalidOperationException
The Scoped Provider has already been assigned to another…
Error message
The Scoped Provider has already been assigned to another page. Expected: '{page.GetType().FullName}' - Found: '{accessor.Page.GetType().FullName}'. What it means
Prism's Navigation attached property (Navigation.Scope) validates that an IScopedProvider is bound to exactly one page. OnNavigationScopeChanged resolves IPageAccessor from the scoped provider; if the provider's Page is already set to a different page, it throws InvalidOperationException, because sharing one scoped service provider across pages would leak scoped state.
Solutions
- Create a new IScopedProvider per page; never reuse one across pages.
- Only set Navigation.Scope with the provider created for that exact page (e.g. via Prism's navigation pipeline).
- If re-navigating, clear/rebuild the scope instead of reassigning it.
- Check for duplicate Scope assignments in XAML and code-behind.
Example fix
// before: reusing parent's scope on child page childPage.SetValue(Navigation.ScopeProperty, parentScope); // after: let Prism create the scope per page, or create a fresh one var childScope = scopeFactory.CreateScopedProvider(childPage); childPage.SetValue(Navigation.ScopeProperty, childScope);
Defensive patterns
Strategy: validation
Validate before calling
if (scopedProvider.Resolve<IPageAccessor>() is { } accessor && accessor.Page is not null && accessor.Page != page)
throw new InvalidOperationException("Scoped provider already bound to a different page"); Type guard
if (newValue is IScopedProvider sp && sp.Resolve<IPageAccessor>().Page is null) { /* safe to attach */ } Try / catch
try
{
Navigation.SetScope(page, scopedProvider);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Scoped Provider"))
{
logger.LogError(ex, "Scoped provider reused across pages");
} Prevention
- Let Prism's navigation pipeline create the scope per page; avoid manual Scope assignment.
- Never share one IScopedProvider between pages.
- Audit XAML/code-behind for duplicate Navigation.Scope assignments.
- Rebuild (not reassign) scopes on page reuse or re-navigation.
When it happens
Trigger: Setting Navigation.ScopeProperty with an IScopedProvider whose IPageAccessor.Page already holds a different page — typically reusing the same scoped provider instance across two pages or assigning the scope property twice with different pages.
Common situations: Manually assigning Navigation.Scope in XAML/code with a provider created for another page; creating one scope in a parent page and attaching it to a pushed child page; navigation page reuse where the provider wasn't reset.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The page type ' ' is not supported.
- Unable to determine the current page.
- NavigationException.NoPageIsRegistered
- The builder does not implement IRegistryAware
- NavigationException.NoPageIsRegistered
AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15).
Data as JSON: /api/errors/517b55f04862440d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs:46
{
if (bindable is not Page page || oldValue == newValue)
{
return;
}
if (oldValue != null && newValue is null && oldValue is IScopedProvider oldProvider)
{
oldProvider.Dispose();
return;
}
if (newValue != null && newValue is IScopedProvider scopedProvider)
{
var accessor = scopedProvider.Resolve<IPageAccessor>();
if (accessor.Page is null)
accessor.Page = page;
else if (accessor.Page != page)
throw new InvalidOperationException($"The Scoped Provider has already been assigned to another page. Expected: '{page.GetType().FullName}' - Found: '{accessor.Page.GetType().FullName}'.");
scopedProvider.IsAttached = true;
}
}
/// <summary>
/// Provides bindable CanNavigate Bindable Property
/// </summary>
public static readonly BindableProperty CanNavigateProperty =
BindableProperty.CreateAttached("CanNavigate",
typeof(bool),
typeof(Navigation),
true,
propertyChanged: OnCanNavigatePropertyChanged);
internal static readonly BindableProperty RaiseCanExecuteChangedInternalProperty =
BindableProperty.CreateAttached("RaiseCanExecuteChangedInternal",
typeof(Action),View on GitHub (pinned to 358118cd64)