stride3d/stride · error · InvalidOperationException

InitializeContentEntity has already been invoked.

Error message

InitializeContentEntity has already been invoked.

What it means

The protected EntityGizmo constructor assigns ContentEntity and guards that it has not been set before. Because ContentEntity is only assigned here, the guard 'InitializeContentEntity has already been invoked' fires when a gizmo's constructor is somehow executed twice for the same instance (chained constructors calling base twice is impossible in C#, so this surfaces mainly through reflection-based instantiation reusing or re-entering a partially initialized instance).

Solutions

  1. Ensure each gizmo instance is constructed exactly once; create a new instance instead of re-running constructors.
  2. In derived gizmos, make sure only one base constructor assigning ContentEntity is invoked per instance.
  3. If using custom instantiation code, always call Activator.CreateInstance rather than reusing a half-initialized object.

Example fix

// before
var gizmo = cachedGizmo;
gizmo.Reinitialize(component); // constructor re-entered
// after
var gizmo = (EntityGizmo<TComponent>)Activator.CreateInstance(gizmoType, component);
Defensive patterns

Strategy: validation

Validate before calling

if (gizmo.ContentEntity != null)
    throw new InvalidOperationException("Gizmo already initialized with a content entity.");

Type guard

bool IsUninitialized(EntityGizmo g) => g.ContentEntity == null;

Try / catch

try { gizmo = CreateGizmo(type, component); }
catch (InvalidOperationException) { gizmo = CreateGizmo(type, component); // construct a fresh instance }

Prevention

When it happens

Trigger: Constructing the same gizmo instance path twice such that the guard sees a non-null ContentEntity — typically via Activator patterns that cache and re-invoke constructors, or a derived class calling a base constructor chain that assigns ContentEntity more than once.

Common situations: Custom gizmo frameworks that re-run construction on cached instances; refactors where a derived gizmo class invokes another constructor of itself that already set ContentEntity via instance state.

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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/EntityGizmo.cs:55

        /// <summary>
        /// Gets the associated scene entity.
        /// </summary>
        public Entity ContentEntity { get; private set; }

        /// <summary>
        /// Gets or sets whether this gizmo is currently selected.
        /// </summary>
        public virtual bool IsSelected { get; set; }

        private IEditorGameComponentGizmoService gizmos;

        private IEditorGameCameraService camera;

        protected EntityGizmo(Entity contentEntity)
        {
            if (contentEntity == null) throw new ArgumentNullException(nameof(contentEntity));
            if (ContentEntity != null) throw new InvalidOperationException("InitializeContentEntity has already been invoked.");
            ContentEntity = contentEntity;
        }

        public override void Initialize(IServiceRegistry services, Scene editorScene)
        {
            base.Initialize(services, editorScene);

            if (GizmoRootEntity != null)
                CollectComponentIds(GizmoRootEntity);

            gizmos = Game.EditorServices.Get<IEditorGameComponentGizmoService>();
            camera = Game.EditorServices.Get<IEditorGameCameraService>();
        }

        /// <inheritdoc/>
        public virtual void Update()
        {
            if (ContentEntity == null || GizmoRootEntity == null || gizmos == null || camera == null)

View on GitHub (pinned to 96fad776d2)