PrismLibrary/Prism · error · InvalidOperationException
Mapping with the given type is already registered
Error message
Mapping with the given type is already registered: {0}. What it means
RegionAdapterMappings.RegisterMapping throws InvalidOperationException (Resources.MappingExistsException) when a mapping for the given control type already exists. The dictionary enforces one adapter per control type to make region adapter resolution deterministic.
Solutions
- Only register mappings for control types that do not yet have a mapping (the built-in ones are pre-registered)
- Remove duplicate RegisterMapping calls for control types already mapped by Prism defaults
- If replacement is truly required, add a non-throwing path: check/replace the mapping via the underlying dictionary or clear it before registering (may require a custom mappings subclass)
- Guard the call by checking whether the type is already mapped before registering
Example fix
// before
protected override void ConfigureRegionAdapterMappings(IRegionAdapterMappings mappings)
{
base.ConfigureRegionAdapterMappings(mappings);
mappings.RegisterMapping<ScrollView, MyScrollViewAdapter>(); // already registered
}
// after
protected override void ConfigureRegionAdapterMappings(IRegionAdapterMappings mappings)
{
base.ConfigureRegionAdapterMappings(mappings);
mappings.RegisterMapping<MyCustomControl, MyCustomControlAdapter>(); // new type only
} Defensive patterns
Strategy: try-catch
Validate before calling
// RegisterMapping does not expose a TryGetValue; only register custom control types bool isNewType = myControlType != typeof(ScrollView) && myControlType != typeof(ContentPresenter);
Try / catch
try { mappings.RegisterMapping<MyControl, MyControlAdapter>(); }
catch (InvalidOperationException) { /* mapping already exists — skip or replace via custom mappings */ } Prevention
- Only call RegisterMapping for your own custom control types
- Remember Prism pre-registers default adapters in ConfigureRegionAdapterMappings
- Call base.ConfigureRegionAdapterMappings once; avoid duplicated startup paths
When it happens
Trigger: Calling RegisterMapping<TControl, TAdapter> twice for the same TControl — most commonly by overriding ConfigureRegionAdapterMappings in a PrismApp-derived class and re-registering a default adapter that Prism already registered internally, or calling the override both in base and derived bootstrapper code.
Common situations: Customizing region adapters in a Prism.Maui app while the base registration already added the default adapter (e.g. re-registering ContentPresenter/ScrollView adapters); duplicate startup code paths running ConfigureRegionAdapterMappings twice.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Layout 's Children property is not empty. This control is…
- regionName
- regionTarget
- The object must be of type
- The IRegionAdapter for the type
AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15).
Data as JSON: /api/errors/5308bedad18245f5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Maui/Prism.Maui/Navigation/Regions/Adapters/RegionAdapterMappings.cs:25
/// <summary>
/// This class maps <see cref="Type"/> with <see cref="IRegionAdapter"/>.
/// </summary>
public class RegionAdapterMappings
{
private readonly Dictionary<Type, IRegionAdapter> mappings = [];
/// <summary>
/// Registers the mapping between a type and an adapter.
/// </summary>
/// <typeparam name="TControl">The type of the control</typeparam>
/// <typeparam name="TAdapter">The type of the IRegionAdapter to use with the TControl</typeparam>
/// <exception cref="InvalidOperationException">Throws <see cref="InvalidOperationException"/> when a mapping has already been defined for a specified control type.</exception>
public void RegisterMapping<TControl, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TAdapter>() where TAdapter : IRegionAdapter
{
var controlType = typeof(TControl);
if (mappings.ContainsKey(controlType))
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
Resources.MappingExistsException, controlType.Name));
var adapter = ContainerLocator.Container.Resolve<TAdapter>();
mappings.Add(controlType, adapter);
}
/// <summary>
/// Removes an existing Registration if one exists and registers the new mapping between a type and an adapter.
/// </summary>
/// <typeparam name="TControl">The type of the control</typeparam>
/// <typeparam name="TAdapter">The type of the IRegionAdapter to use with the TControl</typeparam>
public void RegisterOrReplaceMapping<TControl, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] TAdapter>() where TAdapter : IRegionAdapter
{
var controlType = typeof(TControl);
var adapter = ContainerLocator.Container.Resolve<TAdapter>();
if (mappings.ContainsKey(controlType))View on GitHub (pinned to 358118cd64)