PrismLibrary/Prism · error · InvalidOperationException

Resources.DirectoryNotFound (string.Format with ModulePath)

Error message

Resources.DirectoryNotFound (string.Format with ModulePath)

What it means

DirectoryModuleCatalog (.NET Core/.NET 5+ build) throws InvalidOperationException with the DirectoryNotFound resource formatted with ModulePath when the configured directory does not exist on disk. The message embeds the path, making the failing configuration explicit. Thrown in InnerLoad prior to scanning assemblies.

Solutions

  1. Ensure the directory exists before Load; create it with Directory.CreateDirectory if your app owns it.
  2. Resolve with an absolute path: Path.Combine(AppContext.BaseDirectory, "Modules").
  3. Fix publish settings so module assemblies/folder are copied to output.
  4. Check casing and separators on case-sensitive file systems (Linux).

Example fix

// before
catalog.ModulePath = @"C:\App\Modules"; // invalid on Linux host

// after
catalog.ModulePath = Path.Combine(AppContext.BaseDirectory, "Modules");
Defensive patterns

Strategy: validation

Validate before calling

if (!Directory.Exists(catalog.ModulePath))
    throw new DirectoryNotFoundException($"Modules directory not found: {catalog.ModulePath}");

Type guard

static bool ModulePathExists(string path) => !string.IsNullOrEmpty(path) && Directory.Exists(path);

Try / catch

try { catalog.Load(); }
catch (InvalidOperationException ex) when (ex.Message.Contains(catalog.ModulePath)) { logger.LogError(ex, "Modules directory missing: {Path}", catalog.ModulePath); }

Prevention

When it happens

Trigger: ModulePath points to a nonexistent directory when Load() runs: wrong relative path, folder not published with the app, drive/UNC path unavailable in the deployment environment.

Common situations: Container/Linux deployments where a Windows-style path is invalid; the Modules folder missing from publish output; environment-specific paths (dev vs prod) not updated; working directory differences for hosted services.

Related errors


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

Appendix: source

Thrown at src/Wpf/Prism.Wpf/Modularity/DirectoryModuleCatalog.netcore.cs:39

    /// The directory catalog does not continue to monitor the directory after it has created the initialize catalog.
    /// </remarks>
    public class DirectoryModuleCatalog : ModuleCatalog
    {
        /// <summary>
        /// Directory containing modules to search for.
        /// </summary>
        public string ModulePath { get; set; }

        /// <summary>
        /// Drives the main logic of building the child domain and searching for the assemblies.
        /// </summary>
        protected override void InnerLoad()
        {
            if (string.IsNullOrEmpty(ModulePath))
                throw new InvalidOperationException(Resources.ModulePathCannotBeNullOrEmpty);

            if (!Directory.Exists(ModulePath))
                throw new InvalidOperationException(
                    string.Format(CultureInfo.CurrentCulture, Resources.DirectoryNotFound, ModulePath));

            AppDomain childDomain = AppDomain.CurrentDomain;

            try
            {
                List<string> loadedAssemblies = new List<string>();

                var assemblies = (
                    from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
                    where !(assembly is System.Reflection.Emit.AssemblyBuilder)
                        && assembly.GetType().FullName != "System.Reflection.Emit.InternalAssemblyBuilder"
                        && !String.IsNullOrEmpty(assembly.Location)
                    select assembly.Location
                );

                loadedAssemblies.AddRange(assemblies);

View on GitHub (pinned to 358118cd64)