stride3d/stride · error · InvalidOperationException

This Collidable's should exist

Error message

This Collidable's {nameof(CollidableReference)} should exist

What it means

Register subscribes a CollidableComponent for contact events, which requires the component to already have a CollidableReference assigned by the physics simulation. A null reference means the collidable was never added to (or not yet processed by) the simulation, so there is nothing to listen for.

Solutions

  1. Add/register the CollidableComponent with the simulation first, then call Register after CollidableReference is assigned.
  2. Check collidable.CollidableReference != null before calling Register.
  3. If the component was removed, do not re-register without re-adding it to the simulation.
  4. Defer registration to the next physics update if it was added this frame.

Example fix

// before
contactEvents.Register(myCollider); // CollidableReference still null
// after
simulation.Collidable.Add(myCollider); // simulation assigns reference
if (myCollider.CollidableReference != null)
    contactEvents.Register(myCollider);
Defensive patterns

Strategy: type-guard

Validate before calling

if (collidable.CollidableReference == null)
    throw new InvalidOperationException("Collidable not yet added to the simulation; cannot register for contact events");

Type guard

static bool CanRegister(CollidableComponent c) => c.CollidableReference is not null;

Try / catch

try { contactEvents.Register(collidable); } catch (InvalidOperationException ex) { Logger.Warning($"Skipped contact registration: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling ContactEventsManager.Register(collidable) while collidable.CollidableReference is null — the component has not been added to the simulation's collidables, or the simulation has not yet assigned its handle.

Common situations: Registering a collider/physics component before the Simulation has processed it (e.g. during the same frame it was added, before ApplyDescription/initialization); the component was removed from the scene so its reference was released; wrong simulation instance ordering.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/1d15404f9d8796b5. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/Definitions/Contacts/ContactEventsManager.cs:73

        {
            foreach (var typeStore in workerStore)
            {
                if (typeStore.IsEmpty() == false)
                    throw new InvalidOperationException("Cannot resize the manifold store, manifolds have not been flushed yet");
            }
        }

        _manifoldStoresPerWorker = new IPerTypeManifoldStore[newWorkerCount][];
        for (int i = 0; i < _manifoldStoresPerWorker.Length; i++)
            _manifoldStoresPerWorker[i] = [];
    }

    /// <summary>
    /// Begins listening for events related to the given collidable.
    /// </summary>
    public void Register(CollidableComponent collidable)
    {
        var reference = collidable.CollidableReference ?? throw new InvalidOperationException($"This Collidable's {nameof(CollidableReference)} should exist");
        if (reference.Mobility == CollidableMobility.Static)
            _staticListenerFlags.Add(reference.RawHandleValue, _pool);
        else
            _bodyListenerFlags.Add(reference.RawHandleValue, _pool);
    }

    /// <summary>
    /// Stops listening for events related to the given collidable.
    /// </summary>
    public void Unregister(CollidableComponent collidable)
    {
        var reference = collidable.CollidableReference ?? throw new InvalidOperationException($"This Collidable's {nameof(CollidableReference)} should exist");
        if (reference.Mobility == CollidableMobility.Static)
            _staticListenerFlags.Remove(reference.RawHandleValue);
        else
            _bodyListenerFlags.Remove(reference.RawHandleValue);

        ClearCollisionsOf(collidable, reference.Packed);

View on GitHub (pinned to 96fad776d2)