stride3d/stride · error · InvalidOperationException

The ContentScene has not been initialized yet.

Error message

The ContentScene has not been initialized yet.

What it means

EnsureContentScene is a guard asserting that the editor's ContentScene was already created via InitializeContentScene; if it is still null the editor game is being used before scene initialization and an InvalidOperationException is thrown.

Solutions

  1. Call/await InitializeContentScene before any code that touches ContentScene
  2. Defer scene-dependent work until the editor game's LoadContent/Initialize completed (await editor game startup)
  3. Check why ContentScene is null: the scene asset may have failed to load
  4. If writing an async task, await a task/event signaling scene readiness instead of assuming it exists

Example fix

// before
await someService.Init(editorGame); // touches ContentScene too early
// after
await editorGame.InitializeContentScene();
await someService.Init(editorGame);
Defensive patterns

Strategy: validation

Validate before calling

if (editorGame.ContentScene == null)
    throw new InvalidOperationException("InitializeContentScene must run before scene access");

Type guard

static bool HasContentScene(EntityHierarchyEditorGame g) => g.ContentScene != null;

Try / catch

try { EnsureContentScene(); }
catch (InvalidOperationException) { await editorGame.InitializeContentScene(); }

Prevention

When it happens

Trigger: Calling code that depends on ContentScene (entity manipulation, gizmo/selection services) before InitializeContentScene has run, or after scene initialization failed silently.

Common situations: Editor plugins accessing the scene during early game lifecycle (before LoadContent completes); failed asset load leaving ContentScene null; calling EnsureContentScene-dependent APIs from async tasks that race initialization.

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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/Game/EntityHierarchyEditorGame.cs:224

            }
            catch
            {
                // TODO: Log or rethrow?
                renderEffect.State = RenderEffectState.Error;
                return null;
            }
        }

        /// <summary>
        /// Ensures that the <see cref="ContentScene"/> has been initialized. Otherwise throws an <see cref="InvalidOperationException"/>.
        /// </summary>
        /// <seealso cref="InitializeContentScene"/>
        protected void EnsureContentScene()
        {
            if (ContentScene != null)
                return;

            throw new InvalidOperationException($"The {nameof(ContentScene)} has not been initialized yet.");
        }

        /// <inheritdoc />
        protected override void Initialize()
        {
            base.Initialize();

            // Use a shared database for our shader system
            // TODO: Shaders compiled on main thread won't actually be visible to MicroThread build engine (contentIndexMap are separate).
            // It will still work and cache because EffectCompilerCache caches not only at the index map level, but also at the database level.
            // Later, we probably want to have a GetSharedDatabase() allowing us to mutate it (or merging our results back with IndexFileCommand.AddToSharedGroup()),
            // so that database created with MountDatabase also have all the newest shaders.
            ((IReferencable)effectCompiler).AddReference();
            EffectSystem.Compiler = effectCompiler;

            // Record used effects
            if (effectLogPath != null)
            {

View on GitHub (pinned to 96fad776d2)