PrismLibrary/Prism · error · InvalidOperationException

Resources.MappingExistsException

Error message

Resources.MappingExistsException

What it means

RegionAdapterMappings.RegisterMapping throws InvalidOperationException formatted with MappingExistsException when an adapter mapping for the given controlType already exists. Each control type can be mapped to exactly one IRegionAdapter.

Solutions

  1. Register the custom adapter only once, in one place (e.g. App.CreateContainer/ConfigureDefaultRegionAdapterMappings override), removing duplicates from modules.
  2. If overriding is intended, avoid mapping for an already-mapped type or restructure so your adapter replaces the default during the single registration point.
  3. Track registration with a flag/HashSet so repeated initialization doesn't call RegisterMapping again.

Example fix

// before
mappings.RegisterMapping(typeof(TabControl), myAdapter); // may run twice
// after
if (!mappings.HasMapping(typeof(TabControl))) // guard, or ensure single registration point
    mappings.RegisterMapping(typeof(TabControl), myAdapter);
Defensive patterns

Strategy: validation

Validate before calling

if (mappings.GetMappingOrDefault(controlType) != null)
    return; // already registered
mappings.RegisterMapping(controlType, adapter);

Try / catch

try
{
    mappings.RegisterMapping(controlType, adapter);
}
catch (InvalidOperationException)
{
    // mapping already exists — skip or remove old mapping first
}

Prevention

When it happens

Trigger: Calling RegisterMapping(typeof(SameControl), adapter) twice — e.g. registering a custom adapter in App while a base module/library already registered one for the same type.

Common situations: Two modules each registering an adapter for the same control type during module initialization; duplicate adapter registration code left after a refactor; re-running initialization logic (app restart in-process, repeated ConfigureDefaultRegionAdapterMappings).

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


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/a57182d4fd94f52f. Report an issue: GitHub.

Appendix: source

Thrown at src/Wpf/Prism.Wpf/Navigation/Regions/RegionAdapterMappings.cs:30

        private readonly Dictionary<Type, IRegionAdapter> mappings = new Dictionary<Type, IRegionAdapter>();

        /// <summary>
        /// Registers the mapping between a type and an adapter.
        /// </summary>
        /// <param name="controlType">The type of the control.</param>
        /// <param name="adapter">The adapter to use with the <paramref name="controlType"/> type.</param>
        /// <exception cref="ArgumentNullException">When any of <paramref name="controlType"/> or <paramref name="adapter"/> are <see langword="null" />.</exception>
        /// <exception cref="InvalidOperationException">If a mapping for <paramref name="controlType"/> already exists.</exception>
        public void RegisterMapping(Type controlType, IRegionAdapter adapter)
        {
            if (controlType == null)
                throw new ArgumentNullException(nameof(controlType));

            if (adapter == null)
                throw new ArgumentNullException(nameof(adapter));

            if (mappings.ContainsKey(controlType))
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                                                                  Resources.MappingExistsException, controlType.Name));

            mappings.Add(controlType, adapter);
        }

        /// <summary>
        /// Registers the mapping between a type and an adapter.
        /// </summary>
        /// <typeparam name="TControl">The type of the control</typeparam>
        public void RegisterMapping<TControl>(IRegionAdapter adapter)
        {
            RegisterMapping(typeof(TControl), adapter);
        }

        /// <summary>
        /// Registers the mapping between a type and an adapter.
        /// </summary>
        /// <typeparam name="TControl">The type of the control</typeparam>

View on GitHub (pinned to 358118cd64)