stride3d/stride · error · InvalidOperationException
Input device with Id
Error message
Input device with Id {device.Id} was not registered What it means
InputSourceBase.UnregisterDevice throws when Devices.Remove(device.Id) returns false, i.e. the device being removed was never registered (or was already removed). The input source calls this from Update during device lifecycle changes, so it indicates bookkeeping drift between the concrete source's own collections and the base Devices dictionary.
Solutions
- Only call UnregisterDevice for devices previously registered through RegisterDevice
- Guard removal with Devices.ContainsKey(device.Id) before unregistering
- Fix double-dispose paths so Disconnected/Remove logic runs only once (idempotent flags)
- Keep the subclass's own collection (gamePads, mice, ...) in sync: unregister before removing from it
Example fix
// before
if (Devices.ContainsKey(device.Id))
UnregisterDevice(device);
UnregisterDevice(device); // throws if already removed
// after
if (Devices.ContainsKey(device.Id))
UnregisterDevice(device); Defensive patterns
Strategy: validation
Validate before calling
if (inputSource.Devices.ContainsKey(device.Id)) inputSource.UnregisterDevice(device);
Try / catch
try { source.UnregisterDevice(device); } catch (InvalidOperationException) { /* already unregistered */ } Prevention
- Track which devices you registered so you never unregister unknown ones
- Make removal idempotent with a disposed/removed flag on your device wrapper
- Unregister before removing the device from your own collections
When it happens
Trigger: Calling UnregisterDevice with a device that was never registered via RegisterDevice, or calling it twice for the same device; also triggered internally from Update when a Disconnected event or source logic removes a device whose Id is absent from Devices.
Common situations: Double-dispose of a game controller (Dispose fires Disconnected, source tries to unregister twice); custom simulated-device removal code that forgets to Add first; race between Update's cleanup pass and manual removal in user code.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Input device with Id
- Device with Id ( ) already registered to
- GameContext type is not supported by the InputManager
- value
- value
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4d78a6a6f92749b1.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/InputSourceBase.cs:62
/// Adds the device to the list <see cref="Devices"/>
/// </summary>
/// <param name="device">The device</param>
protected void RegisterDevice(IInputDevice device)
{
if (Devices.ContainsKey(device.Id))
throw new InvalidOperationException($"Input device with Id {device.Id} already registered");
Devices.Add(device.Id, device);
}
/// <summary>
/// CRemoves the device from the list <see cref="Devices"/>
/// </summary>
/// <param name="device">The device</param>
protected void UnregisterDevice(IInputDevice device)
{
if (!Devices.Remove(device.Id))
throw new InvalidOperationException($"Input device with Id {device.Id} was not registered");
}
}
}
View on GitHub (pinned to 96fad776d2)