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

  1. Only call UnregisterDevice for devices previously registered through RegisterDevice
  2. Guard removal with Devices.ContainsKey(device.Id) before unregistering
  3. Fix double-dispose paths so Disconnected/Remove logic runs only once (idempotent flags)
  4. 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

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


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)