RomM version:
4.9.2
Describe the bug:
Connecting a gamepad triggers an uncaught TypeError inside GamepadHandler's
event dispatch, which appears to kill the gamepad polling loop entirely —
the controller enumerates and appears selectable in the UI, but no button
input is ever registered afterward. This does NOT reproduce in Safari with
the same controller and same page — appears to be Brave-specific, possibly
related to Brave Shields modifying Gamepad API data.
Environment:
- Browser: Brave (Chromium-based), latest — NOT reproducible in Safari
- OS: macOS
- Deployment: RomM (bundles EmulatorJS)
- Controller: Xbox One Wireless Controller, model 1708
- Connection type: Bluetooth
Steps to reproduce:
- Fully disconnect/forget any previously paired gamepads
- Connect a single Xbox One Wireless Controller (model 1708) via Bluetooth
- Restart Brave with a single tab open to the game
- Load the game, click into the emulator canvas for focus
- Press any button on the controller
Expected behavior:
Gamepad input registers and the controller becomes usable in-game.
Actual behavior:
Console throws an uncaught TypeError immediately, and no gamepad input
is ever registered afterward, even though the controller shows as
selectable/detected in the emulator's control settings. Confirmed NOT
reproducible in Safari under identical conditions (same page, same
controller, same connection method), suggesting a Brave-specific
difference in how it exposes gamepad data to the page — possibly related
to Brave Shields' anti-fingerprinting modifications to hardware APIs.
Console error:
Uncaught TypeError: Cannot read properties of undefined (reading 'id')
at EmulatorJS.gamepadEvent (emulator.min.js:1:339108)
at GamepadHandler.dispatchEvent (emulator.min.js:1:206364)
at emulator.min.js:1:205619
at Array.forEach ()
at emulator.min.js:1:205437
at Array.forEach ()
at emulator.min.js:1:204995
at Array.forEach ()
at GamepadHandler.updateGamepadState (emulator.min.js:1:204942)
at GamepadHandler.loop (emulator.min.js:1:204688)
Screenshots

Server:
- OS: Synology DSM 7.3.2-86009 Update 3
Client:
- Device: MacBook Air
- OS: macOS Tahoe 26.5.2
- Browser: Brave
- Version: 1.92.134
Additional notes
Occurs on a clean, fresh connection — not caused by rapid reconnect/
disconnect cycling. The nested Array.forEach calls suggest
updateGamepadState iterates a gamepad list that can contain
null/undefined/partially-populated entries, and gamepadEvent/
dispatchEvent don't appear to guard against a missing id before
reading it. This only manifests in Brave and not Safari, suggesting the
gamepad object Brave hands to the page differs somehow. Brave Shields
was ruled out as the cause — disabled Shields entirely for the site and
restarted the browser, issue persisted identically. The root difference
is likely something deeper in Brave's Chromium fork's Gamepad API
implementation rather than a Shields/privacy feature. Regardless of root
cause, EmulatorJS's handler crashing on this input rather than degrading
gracefully is worth hardening against.
RomM version:
4.9.2
Describe the bug:
Connecting a gamepad triggers an uncaught TypeError inside GamepadHandler's
event dispatch, which appears to kill the gamepad polling loop entirely —
the controller enumerates and appears selectable in the UI, but no button
input is ever registered afterward. This does NOT reproduce in Safari with
the same controller and same page — appears to be Brave-specific, possibly
related to Brave Shields modifying Gamepad API data.
Environment:
Steps to reproduce:
Expected behavior:
Gamepad input registers and the controller becomes usable in-game.
Actual behavior:
Console throws an uncaught TypeError immediately, and no gamepad input
is ever registered afterward, even though the controller shows as
selectable/detected in the emulator's control settings. Confirmed NOT
reproducible in Safari under identical conditions (same page, same
controller, same connection method), suggesting a Brave-specific
difference in how it exposes gamepad data to the page — possibly related
to Brave Shields' anti-fingerprinting modifications to hardware APIs.
Console error:
Uncaught TypeError: Cannot read properties of undefined (reading 'id')
at EmulatorJS.gamepadEvent (emulator.min.js:1:339108)
at GamepadHandler.dispatchEvent (emulator.min.js:1:206364)
at emulator.min.js:1:205619
at Array.forEach ()
at emulator.min.js:1:205437
at Array.forEach ()
at emulator.min.js:1:204995
at Array.forEach ()
at GamepadHandler.updateGamepadState (emulator.min.js:1:204942)
at GamepadHandler.loop (emulator.min.js:1:204688)
Screenshots

Server:
Client:
Additional notes
Occurs on a clean, fresh connection — not caused by rapid reconnect/
disconnect cycling. The nested
Array.forEachcalls suggestupdateGamepadStateiterates a gamepad list that can containnull/undefined/partially-populated entries, andgamepadEvent/dispatchEventdon't appear to guard against a missingidbeforereading it. This only manifests in Brave and not Safari, suggesting the
gamepad object Brave hands to the page differs somehow. Brave Shields
was ruled out as the cause — disabled Shields entirely for the site and
restarted the browser, issue persisted identically. The root difference
is likely something deeper in Brave's Chromium fork's Gamepad API
implementation rather than a Shields/privacy feature. Regardless of root
cause, EmulatorJS's handler crashing on this input rather than degrading
gracefully is worth hardening against.