stride3d/stride · error · InvalidOperationException
Input device was not registered
Error message
Input device was not registered
What it means
OnInputDeviceRemoved validates that the device being removed is currently registered; if devices.Contains(device) is false, Stride throws InvalidOperationException, preventing double-removal or removal of foreign devices from internal collections.
Solutions
- Only raise CollectionChanged Remove for devices previously announced with Add.
- Guard custom source teardown so each device removal fires once.
- Verify device lifetime management in the custom IInputSource implementation.
Example fix
// before Devices.Remove(device); Devices.Remove(device); // second raise throws // after if (Devices.Contains(device)) Devices.Remove(device);
Defensive patterns
Strategy: type-guard
Validate before calling
bool CanRemove(IInputDevice d) => d != null && devices.Contains(d);
Type guard
bool IsRegistered(InputManager input, IInputDevice d) => input.Sources.SelectMany(s => s.Devices).Any(x => ReferenceEquals(x, d));
Try / catch
try { /* source teardown */ }
catch (InvalidOperationException ex) when (ex.Message == "Input device was not registered") { /* already removed: ignore */ } Prevention
- Raise Remove only for devices previously announced via Add.
- Make custom source teardown idempotent (remove each device once).
- Serialize connect/disconnect handling to avoid double teardown.
When it happens
Trigger: A source raising a Remove notification for a device that was never added, or raising Remove twice for the same device; a device from one source being removed via another source's collection.
Common situations: Custom input sources with buggy device lifecycle (double Remove on shutdown); device removal racing with its own earlier removal; sources disposing without having added devices.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- The event type was not registered with the input manager…
- Input Source already added
- Could not find asset
- Expect name1=value1;name2=value2 format.
- assetItem must be an absolute path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0518cb2005803030.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/InputManager.cs:829
}
else if (device is IGamePadDevice)
{
RegisterGamePad((IGamePadDevice)device);
gamePads.Sort((l, r) => -l.Priority.CompareTo(r.Priority));
}
else if (device is ISensorDevice)
{
RegisterSensor((ISensorDevice)device);
}
UpdateConnectedDevices();
DeviceAdded?.Invoke(this, new DeviceChangedEventArgs { Device = device, Source = source, Type = DeviceChangedEventType.Added });
}
private void OnInputDeviceRemoved(IInputDevice device)
{
if (!devices.Contains(device))
throw new InvalidOperationException("Input device was not registered");
var source = device.Source;
devices.Remove(device);
devicesById.Remove(device.Id);
if (device is IKeyboardDevice)
{
UnregisterKeyboard((IKeyboardDevice)device);
}
else if (device is IPointerDevice)
{
UnregisterPointer((IPointerDevice)device);
}
else if (device is IGameControllerDevice)
{
UnregisterGameController((IGameControllerDevice)device);
}
else if (device is IGamePadDevice)View on GitHub (pinned to 96fad776d2)