stride3d/stride · error · InvalidOperationException
The SessionViewModel class can be instanced only once.
Error message
The SessionViewModel class can be instanced only once.
What it means
SessionViewModel enforces a singleton pattern via a static Instance field. The constructor throws InvalidOperationException if Instance is already set, because the class can only be instantiated once per editor process. After construction it assigns Instance = this.
Solutions
- Dispose/close the existing SessionViewModel (which should null Instance) before creating a new one.
- Keep a single app-wide SessionViewModel and reuse it instead of constructing new ones.
- In tests, reset the singleton (dispose and clear Instance) in test teardown.
- Catch InvalidOperationException to detect an existing session and route to the existing instance.
Example fix
// before var newSession = SessionViewModel.CreateInstance(provider, logger, session, editor); // Instance still set // after oldSession.Dispose(); // clears Instance var newSession = SessionViewModel.CreateInstance(provider, logger, session, editor);
Defensive patterns
Strategy: validation
Validate before calling
if (SessionViewModel.Instance != null)
throw new InvalidOperationException("SessionViewModel already exists; dispose it first"); Try / catch
try { session = SessionViewModel.CreateInstance(sp, log, ps, editor); }
catch (InvalidOperationException) { session = SessionViewModel.Instance; /* reuse singleton */ } Prevention
- Treat SessionViewModel as a singleton app-wide
- Dispose in teardown to clear Instance
- In tests, reset the singleton between test cases
When it happens
Trigger: Constructing (via CreateInstance) a second SessionViewModel while the previous instance is still alive and Instance is non-null.
Common situations: Opening a second editor session or reloading a session without disposing the first; unit tests that construct SessionViewModel multiple times without cleanup.
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
- Trying to dispose a lock that has already been released.
- The ContentScene has not been initialized yet.
- The entity to insert has already been destroyed
- Unable to have two sessions at the same time
- An instance of WindowManager is already existing.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0aac72d5531ae50d.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Core.Assets.Editor/ViewModel/SessionViewModel.cs:563
var documentationService = ServiceProvider.Get<UserDocumentationService>();
foreach (var packageAssembly in LocalPackages.SelectMany(p => p.LoadedAssemblies))
{
if (packageAssembly.Assembly != null)
Task.Run(() => documentationService.CacheAssemblyDocumentation(packageAssembly.Assembly));
}
}
private SessionViewModel(IViewModelServiceProvider serviceProvider, ILogger logger, [NotNull] PackageSession session, [NotNull] EditorViewModel editor)
: base(serviceProvider)
{
if (editor == null) throw new ArgumentNullException(nameof(editor));
if (editor.Session != null) throw new InvalidOperationException("Unable to have two sessions at the same time");
Editor = editor;
this.session = session;
if (Instance != null)
throw new InvalidOperationException("The SessionViewModel class can be instanced only once.");
Instance = this;
// Initialize the dirtiable manager for all our dirtiable objects
undoRedoService = ServiceProvider.Get<IUndoRedoService>();
// Gather all data from plugins
PluginService.RegisterSession(this, logger);
// Initialize the undo/redo debug view model
undoRedoStackPage = EditorDebugTools.CreateUndoRedoDebugPage(undoRedoService, "Undo/redo stack");
ActionHistory = new ActionHistoryViewModel(this);
// Initialize the node container used for asset properties
AssetNodeContainer = new SessionNodeContainer(this) { NodeBuilder = { NodeFactory = new AssetNodeFactory() } };
// Initialize the view model that will manage the properties of the assets selected on the main asset view
AssetViewProperties = new SessionObjectPropertiesViewModel(this);View on GitHub (pinned to 96fad776d2)