PrismLibrary/Prism · critical · InvalidOperationException

IModuleCatalog was null

Error message

IModuleCatalog was null

What it means

PrismBootstrapperBase.RegisterRequiredTypes validates that the module catalog (_moduleCatalog) was created before registering required types with the DI container. If it is null, the app cannot function (no module metadata) and an InvalidOperationException is thrown during Initialize.

Solutions

  1. Ensure CreateModuleCatalog override returns a valid IModuleCatalog (e.g. new ModuleCatalog()).
  2. Call base.CreateModuleCatalog()/base initialization steps when overriding bootstrapper methods.
  3. If using ConfigureModuleCatalog, verify the base Initialize pipeline still runs to assign _moduleCatalog.
  4. Check custom Initialize overrides don't skip RegisterRequiredTypes order.

Example fix

// before
protected override IModuleCatalog CreateModuleCatalog() => null;
// after
protected override IModuleCatalog CreateModuleCatalog() => new ModuleCatalog();
Defensive patterns

Strategy: validation

Validate before calling

protected override IModuleCatalog CreateModuleCatalog()
    => base.CreateModuleCatalog() ?? throw new InvalidOperationException("CreateModuleCatalog must not return null");

Type guard

bool HasCatalog(IModuleCatalog? c) => c is not null;

Try / catch

try { bootstrapper.Initialize(); }
catch (InvalidOperationException ex) when (ex.Message == "IModuleCatalog was null") { /* check CreateModuleCatalog override */ }

Prevention

When it happens

Trigger: Overriding CreateModuleCatalog (or the catalog setup path) and returning null, or overriding RegisterRequiredTypes/Initialize such that _moduleCatalog was never assigned, or a custom bootstrapper flow that skips catalog creation.

Common situations: Custom bootstrapper overrides that forget to call base methods; CreateModuleCatalog returning null by mistake; copy-pasted bootstrapper code from a different Prism version where catalog creation differs; module catalog configured conditionally and the condition never true.

Related errors


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

Appendix: source

Thrown at src/Avalonia/Prism.Avalonia/PrismBootstrapperBase.cs:109

        /// <summary>
        /// Creates the <see cref="IModuleCatalog"/> used by Prism.
        /// </summary>
        ///  <remarks>
        /// The base implementation returns a new ModuleCatalog.
        /// </remarks>
        protected virtual IModuleCatalog CreateModuleCatalog()
        {
            return new ModuleCatalog();
        }

        /// <summary>
        /// Registers all types that are required by Prism to function with the container.
        /// </summary>
        /// <param name="containerRegistry"></param>
        protected virtual void RegisterRequiredTypes(IContainerRegistry containerRegistry)
        {
            if (_moduleCatalog == null)
                throw new InvalidOperationException("IModuleCatalog was null");

            containerRegistry.RegisterRequiredTypes(_moduleCatalog);
        }

        /// <summary>
        /// Used to register types with the container that will be used by your application.
        /// </summary>
        protected abstract void RegisterTypes(IContainerRegistry containerRegistry);

        /// <summary>
        /// Configures the <see cref="IRegionBehaviorFactory"/>.
        /// This will be the list of default behaviors that will be added to a region.
        /// </summary>
        protected virtual void ConfigureDefaultRegionBehaviors(IRegionBehaviorFactory regionBehaviors)
        {
            regionBehaviors?.RegisterDefaultRegionBehaviors();
        }

View on GitHub (pinned to 358118cd64)