stride3d/stride · error · InvalidOperationException

Unable to have two sessions at the same time

Error message

Unable to have two sessions at the same time

What it means

The private SessionViewModel constructor validates that the EditorViewModel passed in is not already attached to another session. If editor.Session is non-null, it throws InvalidOperationException because two SessionViewModels cannot share one editor. This protects the editor-to-session one-to-one relationship.

Solutions

  1. Detach the editor from its current session (set editor.Session = null via the proper teardown) before constructing a new SessionViewModel.
  2. Create a fresh EditorViewModel for each new SessionViewModel.
  3. Verify lifecycle order: dispose the old SessionViewModel before creating a new one with the same editor.
  4. Catch InvalidOperationException during session reload and fall back to creating a new editor instance.

Example fix

// before
var session = SessionViewModel.CreateInstance(provider, logger, packageSession, existingEditor);
// after
existingEditor.Session = null; // detach from previous session
var session = SessionViewModel.CreateInstance(provider, logger, packageSession, existingEditor);
Defensive patterns

Strategy: validation

Validate before calling

if (editor.Session != null)
    throw new InvalidOperationException("Editor already attached to a session; detach first");

Try / catch

try { session = SessionViewModel.CreateInstance(sp, log, ps, editor); }
catch (InvalidOperationException) { editor = new EditorViewModel(...); session = SessionViewModel.CreateInstance(sp, log, ps, editor); }

Prevention

When it happens

Trigger: Constructing a SessionViewModel with an EditorViewModel whose Session property is already set, i.e. reusing an editor that already has a session attached.

Common situations: Opening a second session/editor window reusing a cached EditorViewModel; reloading a session without detaching the editor from the old SessionViewModel first.

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/d49a9f3092cb9301. Report an issue: GitHub.

Appendix: source

Thrown at sources/editor/Stride.Core.Assets.Editor/ViewModel/SessionViewModel.cs:557

            }
        }

        private void LoadDocumentation()
        {
            // Load documentation into cache
            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);

View on GitHub (pinned to 96fad776d2)