stride3d/stride · error · InvalidOperationException

ApplicationDataSubDirectory cannot be modified after the…

Error message

ApplicationDataSubDirectory cannot be modified after the VirtualFileSystem has been initialized.

What it means

PlatformFolders.ApplicationDataSubDirectory configures the subfolder under the user's application-data directory that Stride's VirtualFileSystem mounts at startup. Once the VFS is initialized the mount points are baked in, so the setter throws InvalidOperationException if changed afterwards.

Solutions

  1. Set ApplicationDataSubDirectory as the first thing in Main/Program before constructing any Stride runtime objects.
  2. Restructure code so the value comes from configuration read before engine initialization.
  3. If it must change at runtime, restart the application with the new value rather than mutating it.

Example fix

// before
static void Main() {
  using var game = new Game();
  PlatformFolders.ApplicationDataSubDirectory = "MyApp"; // too late
}
// after
static void Main() {
  PlatformFolders.ApplicationDataSubDirectory = "MyApp";
  using var game = new Game();
}
Defensive patterns

Strategy: validation

Validate before calling

if (PlatformFolders.IsVirtualFileSystemInitialized)
    throw new InvalidOperationException("Set ApplicationDataSubDirectory earlier in startup");

Try / catch

try { PlatformFolders.ApplicationDataSubDirectory = dir; }
catch (InvalidOperationException)
{
    // VFS already initialized: fail startup or restart with the right value
}

Prevention

When it happens

Trigger: Setting PlatformFolders.ApplicationDataSubDirectory after anything has triggered VFS initialization (e.g. after creating a Game, database, or touching virtual file system paths).

Common situations: Assigning the property in game-loop or service-constructor code instead of the very start of Main; a static initializer elsewhere touching the file system first and reordering startup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/cacccca7208ed992. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core/PlatformFolders.cs:58

    /// <summary>
    /// The application data directory, where data is deployed.
    /// It could be read-only on some platforms.
    /// </summary>
    public static readonly string ApplicationDataDirectory = GetApplicationDataDirectory();

    /// <summary>
    /// The (optional) application data subdirectory. If not null or empty, /data will be mounted on <see cref="ApplicationDataDirectory"/>/<see cref="ApplicationDataSubDirectory"/>
    /// </summary>
    /// <remarks>This property should not be written after the VirtualFileSystem static initialization. If so, an InvalidOperationExeception will be thrown.</remarks>
    public static string ApplicationDataSubDirectory
    {
        get { return applicationDataSubDirectory; }

        set
        {
            if (IsVirtualFileSystemInitialized)
                throw new InvalidOperationException("ApplicationDataSubDirectory cannot be modified after the VirtualFileSystem has been initialized.");

            applicationDataSubDirectory = value;
        }
    }

    /// <summary>
    /// The application directory, where assemblies are deployed.
    /// It could be read-only on some platforms.
    /// </summary>
    public static readonly string ApplicationBinaryDirectory = GetApplicationBinaryDirectory();

    /// <summary>
    /// Get the path to the application executable.
    /// </summary>
    /// <remarks>Might be null if start executable is unknown.</remarks>
    public static readonly string? ApplicationExecutablePath = GetApplicationExecutablePath();

    private static string applicationDataSubDirectory = string.Empty;

View on GitHub (pinned to 96fad776d2)