stride3d/stride · error · InvalidOperationException

Not running.

Error message

Not running.

What it means

GameSystemCollection.UnloadContent requires the collection to be in the ContentLoaded state; otherwise it throws this InvalidOperationException. Unloading content only makes sense after LoadContent has succeeded, so any other state is an invalid lifecycle transition.

Solutions

  1. Only call UnloadContent when State == GameSystemState.ContentLoaded
  2. Guard cleanup code with a state check or wrap in a lifecycle helper idempotent across states
  3. Prefer Dispose/normal game shutdown which manages unloading correctly

Example fix

// before
if (shutdown) { systems.UnloadContent(); }
// after
if (shutdown && systems.State == GameSystemState.ContentLoaded) { systems.UnloadContent(); }
Defensive patterns

Strategy: validation

Validate before calling

if (systems.State == GameSystemState.ContentLoaded) systems.UnloadContent();

Try / catch

try { systems.UnloadContent(); } catch (InvalidOperationException ex) when (ex.Message == "Not running.") { /* nothing to unload */ }

Prevention

When it happens

Trigger: Calling UnloadContent() before LoadContent(), calling it twice, or calling it before Initialize on a GameSystemCollection whose State is None or Initialized.

Common situations: Double-unload in shutdown/cleanup code; manual lifecycle management in custom hosts; exception during LoadContent leaving state inconsistent then attempting unload.

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

Appendix: source

Thrown at sources/engine/Stride.Games/GameSystemCollection.cs:178

            }

            foreach (var contentable in currentlyContentGameSystems)
            {
                using (var profile = Profiler.Begin(GameProfilingKeys.GameSystemLoadContent, GetGameSystemName(contentable)))
                    contentable.LoadContent();
            }

            currentlyContentGameSystems.Clear();
        }

        /// <summary>
        /// Called when graphics resources need to be unloaded. Override this method to unload any game-specific graphics resources.
        /// </summary>
        public virtual void UnloadContent()
        {
            if (State != GameSystemState.ContentLoaded)
            {
                throw new InvalidOperationException("Not running.");
            } 
            
            State = GameSystemState.Initialized;

            lock (contentableGameSystems)
            {
                foreach (var contentable in contentableGameSystems)
                {
                    currentlyContentGameSystems.Add(contentable);
                }
            }

            foreach (var contentable in currentlyContentGameSystems)
            {
                contentable.UnloadContent();
            }

            currentlyContentGameSystems.Clear();

View on GitHub (pinned to 96fad776d2)