Skip to content

[Bug] Brave Browser Xbox One Controller Error #3710

Description

@JohnGreen1

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:

  1. Fully disconnect/forget any previously paired gamepads
  2. Connect a single Xbox One Wireless Controller (model 1708) via Bluetooth
  3. Restart Brave with a single tab open to the game
  4. Load the game, click into the emulator canvas for focus
  5. 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
Image

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    emulationEmulator.js bugs or feature requests

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions