stride3d/stride · error · InvalidOperationException
Trying to remove unregistered collider
Error message
Trying to remove unregistered collider
What it means
NavigationMeshBuilder.Remove unregisters a collider by its component Id. Throwing InvalidOperationException when the Id is not registered catches lifecycle bugs where removal happens for a collider that was never added or was already removed.
Solutions
- Check that the collider was registered with this builder before removing (track registration yourself or expose the registered set)
- Make add/remove lifecycle symmetric: remove only in response to the matching removal of a previously added component
- Swallow the case intentionally by checking membership first if double-removal is expected in your teardown flow
Example fix
// before
builder.Remove(colliderData); // may be unregistered
// after
if (registered.Contains(colliderData.Component.Id))
builder.Remove(colliderData); Defensive patterns
Strategy: validation
Validate before calling
// only remove what you added
if (addedColliders.Remove(colliderData))
builder.Remove(colliderData); Type guard
null
Try / catch
try
{
builder.Remove(colliderData);
}
catch (InvalidOperationException)
{
// not registered; ignore during teardown
} Prevention
- Keep a local record of what was added to which builder
- Make teardown idempotent and check membership before Remove
- Remove on the same builder instance that performed Add
When it happens
Trigger: Calling Remove(StaticColliderData) for a component that was never passed to Add, calling Remove twice for the same component, or removing after the builder state was reset.
Common situations: Asymmetric add/remove lifecycle in scene teardown; removing a collider from a different NavigationMeshBuilder instance than the one that added it; scripts running cleanup on scene unload twice.
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
- This instance doesn't contain any path. Use Push() methods…
- Item belongs to another PriorityNodeQueue.
- The control corresponding to the given parentId is a…
- Invoking ShouldStayOpen before the work is finished.
- Cannot add a same component multiple times. Already set at…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/596bf24f0b65d247.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Navigation/NavigationMeshBuilder.cs:72
lock (colliders)
{
if (registeredGuids.Contains(colliderData.Component.Id))
throw new InvalidOperationException("Duplicate collider added");
colliders.Add(colliderData);
registeredGuids.Add(colliderData.Component.Id);
}
}
/// <summary>
/// Removes a specific collider from the builder
/// </summary>
/// <param name="colliderData">The collider data object to remove</param>
public void Remove(StaticColliderData colliderData)
{
lock (colliders)
{
if (!registeredGuids.Contains(colliderData.Component.Id))
throw new InvalidOperationException("Trying to remove unregistered collider");
colliders.Remove(colliderData);
registeredGuids.Remove(colliderData.Component.Id);
}
}
/// <summary>
/// Performs the build of a navigation mesh
/// </summary>
/// <param name="buildSettings">The build settings to pass to recast</param>
/// <param name="groups">A collection of agent settings to use, this will generate a layer in the navigation mesh for every agent settings in this collection (in the same order)</param>
/// <param name="includedCollisionGroups">The collision groups that will affect which colliders are considered solid</param>
/// <param name="boundingBoxes">A collection of bounding boxes to use as the region for which to generate navigation mesh tiles</param>
/// <param name="cancellationToken">A cancellation token to interrupt the build process</param>
/// <returns>The build result</returns>
public NavigationMeshBuildResult Build(NavigationMeshBuildSettings buildSettings, ICollection<NavigationMeshGroup> groups, CollisionFilterGroupFlags includedCollisionGroups,
ICollection<BoundingBox> boundingBoxes, CancellationToken cancellationToken)
{
var lastCache = oldNavigationMesh?.Cache;View on GitHub (pinned to 96fad776d2)