stride3d/stride · error · InvalidOperationException

A Virtual File Provider with the root path

Error message

A Virtual File Provider with the root path "{provider.RootPath}" already exists.

What it means

VirtualFileSystem.RegisterProvider maintains a static registry keyed by provider RootPath; only one provider may exist per root path. If a provider with a non-null RootPath is registered and another provider (or the same one twice) already occupies that key, the TryAdd fails and this InvalidOperationException is thrown.

Solutions

  1. Check providers with VirtualFileSystem.GetProvider(rootPath) before calling RegisterProvider, or skip registration if it returns non-null.
  2. Call VirtualFileSystem.UnregisterProvider(rootPath) for stale providers before re-registering.
  3. Remove duplicate initialization code paths so the provider is registered exactly once per process.
  4. Use a distinct RootPath for the new provider if both mounts are genuinely needed.

Example fix

// before
VirtualFileSystem.RegisterProvider(new DatabaseFileProvider(mount));
// after
if (VirtualFileSystem.GetProvider(mount) == null)
    VirtualFileSystem.RegisterProvider(new DatabaseFileProvider(mount));
Defensive patterns

Strategy: validation

Validate before calling

if (VirtualFileSystem.GetProvider(provider.RootPath) == null)
    VirtualFileSystem.RegisterProvider(provider);

Try / catch

try { VirtualFileSystem.RegisterProvider(provider); }
catch (InvalidOperationException) { /* provider for this root already mounted — reuse it */ }

Prevention

When it happens

Trigger: Calling VirtualFileSystem.RegisterProvider twice with providers having the same RootPath (e.g. mounting '/assets' twice), or registering a provider whose root path collides with a provider auto-registered during engine startup.

Common situations: Game/plugins initializing asset systems in both app code and a bootstrap that runs twice (e.g. constructor + static initializer); test suites creating providers per test without unregistering via UnregisterProvider; duplicate mount entries in config.

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 stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e7a5d26580e36c6c. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.IO/VirtualFileSystem.cs:120

    /// <value>The providers.</value>
    public static IEnumerable<IVirtualFileProvider> Providers
    {
        get
        {
            return providers.Values;
        }
    }

    /// <summary>
    /// Registers the specified virtual file provider at the specified mount location.
    /// </summary>
    /// <param name="provider">The provider.</param>
    public static void RegisterProvider(IVirtualFileProvider provider)
    {
        if (provider.RootPath != null)
        {
            if (!providers.TryAdd(provider.RootPath, provider))
                throw new InvalidOperationException($"A Virtual File Provider with the root path \"{provider.RootPath}\" already exists.");
        }
    }

    /// <summary>
    /// Unregisters the specified virtual file provider.
    /// </summary>
    /// <param name="provider">The provider.</param>
    /// <param name="dispose">Indicate that the provider should be disposed, if it inherits from IDisposable interface.</param>
    public static void UnregisterProvider(IVirtualFileProvider provider, bool dispose = true)
    {
        var mountPoints = providers.Where(x => x.Value == provider).ToArray();
        foreach (var mountPoint in mountPoints)
            providers.Remove(mountPoint.Key);
    }

    /// <summary>
    /// Mounts the specified path in the specified virtual file mount point.
    /// </summary>

View on GitHub (pinned to 96fad776d2)