PrismLibrary/Prism · error · InvalidOperationException

Resources.AdapterInvalidTypeException

Error message

Resources.AdapterInvalidTypeException

What it means

RegionAdapterBase<T>.GetCastedObject casts the regionTarget control to the adapter's generic type T; if the control does not implement/inherit T, it throws InvalidOperationException with AdapterInvalidTypeException naming typeof(T).Name. This guards that a region adapter is only applied to control types it supports.

Solutions

  1. Make the control derive from (or implement) the adapter's required type T, e.g. derive from ContentControl for ContentControlRegionAdapter.
  2. Register the adapter only for the correct type in RegionAdapterMappings: RegisterMapping(typeof(CorrectControl), adapter).
  3. Write a dedicated IRegionAdapter for the custom control type instead of reusing an incompatible one.

Example fix

// before
containerRegistry.RegisterAdapterForSpecificType<StackPanel, MyContentControlAdapter>();
// after
class MyPanel : ContentControl { ... }
containerRegistry.RegisterAdapterForSpecificType<MyPanel, MyContentControlAdapter>();
Defensive patterns

Strategy: validation

Validate before calling

if (!(regionTarget is ContentControl))
    throw new InvalidOperationException("This adapter requires a ContentControl-derived target.");

Type guard

static bool SupportsAdapter<T>(object control) where T : class => control is T;

Try / catch

try
{
    adapter.Initialize(control, regionName);
}
catch (InvalidOperationException ex)
{
    logger.LogError(ex, "Control type not supported by this region adapter.");
}

Prevention

When it happens

Trigger: Registering a RegionAdapterMappings entry for a control type (or derived type) that the adapter does not support — e.g. mapping a custom ContentControl-derived adapter to a control that isn't a ContentControl, then initializing a region on that control.

Common situations: Custom controls that look like the base type but derive from a different branch; adapting a third-party control with an adapter built for stock Prism controls; mapping changes after upgrading Prism where base-type expectations changed.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Wpf/Prism.Wpf/Navigation/Regions/RegionAdapterBase.cs:134

        /// <param name="regionTarget">The object to adapt.</param>
        protected abstract void Adapt(IRegion region, T regionTarget);

        /// <summary>
        /// Template method to create a new instance of <see cref="IRegion"/>
        /// that will be used to adapt the object.
        /// </summary>
        /// <returns>A new instance of <see cref="IRegion"/>.</returns>
        protected abstract IRegion CreateRegion();

        private static T GetCastedObject(object regionTarget)
        {
            if (regionTarget == null)
                throw new ArgumentNullException(nameof(regionTarget));

            T castedObject = regionTarget as T;

            if (castedObject == null)
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.AdapterInvalidTypeException, typeof(T).Name));

            return castedObject;
        }

        private static void SetObservableRegionOnHostingControl(IRegion region, T regionTarget)
        {
            DependencyObject targetElement = regionTarget as DependencyObject;

            if (targetElement != null)
            {
                // Set the region as a dependency property on the control hosting the region
                // Because we are using an observable region, the hosting control can detect that the
                // region has actually been created. This is an ideal moment to hook up custom behaviors
                RegionManager.GetObservableRegion(targetElement).Value = region;
            }
        }
    }
}

View on GitHub (pinned to 358118cd64)