When the BLE controller emits a Hardware Error HCI event, the process crashes with:
Apr 29 18:44:52 roeimachine npm[615]: Uncaught Exception: TypeError: hardwareErrorCallback is not a function
Apr 29 18:44:52 roeimachine npm[615]: at handleHardwareError (/opt/openrowingmonitor/node_modules/ble-host/lib/internal/adapter.js:844:3)
Apr 29 18:44:52 roeimachine npm[615]: at HciSocket.onData (/opt/openrowingmonitor/node_modules/ble-host/lib/internal/adapter.js:1182:31)
Apr 29 18:44:52 roeimachine npm[615]: at HciSocket.emit (node:events:519:28)
Apr 29 18:44:52 roeimachine npm[615]: at /opt/openrowingmonitor/node_modules/hci-socket/lib/hci-socket.js:105:9
Apr 29 18:44:52 roeimachine npm[685]: 2026-04-29 18:44:52 sigHandler: Unhandled signal 15, terminating
Apr 29 18:44:52 roeimachine npm[615]: OpenRowingMonitor shutdown at 18:44, at 2543.14435 seconds,distance 9172.7m
Apr 29 18:44:52 roeimachine npm[615]: /opt/openrowingmonitor/node_modules/ble-host/lib/internal/adapter.js:844
Apr 29 18:44:52 roeimachine npm[615]: hardwareErrorCallback(hardwareCode);
Apr 29 18:44:52 roeimachine npm[615]: ^
Apr 29 18:44:52 roeimachine npm[615]: TypeError: hardwareErrorCallback is not a function
Apr 29 18:44:52 roeimachine npm[615]: at handleHardwareError (/opt/openrowingmonitor/node_modules/ble-host/lib/internal/adapter.js:844:3)
Apr 29 18:44:52 roeimachine npm[615]: at HciSocket.onData (/opt/openrowingmonitor/node_modules/ble-host/lib/internal/adapter.js:1182:31)
Apr 29 18:44:52 roeimachine npm[615]: at HciSocket.emit (node:events:519:28)
Apr 29 18:44:52 roeimachine npm[615]: at /opt/openrowingmonitor/node_modules/hci-socket/lib/hci-socket.js:105:9
I beleive the root cause is a missing parameter in the module export at the bottom of lib/internal/adapter.js. The hardwareErrorCallback argument is accepted by HciAdapter internally but is never forwarded from the exported factory function:
// Current code - hardwareErrorCallback is silently dropped:
module.exports = function(transport) {
return new HciAdapter(transport);
};
// Should be:
module.exports = function(transport, hardwareErrorCallback) {
return new HciAdapter(transport, hardwareErrorCallback);
};
As a result, hardwareErrorCallback is always undefined inside HciAdapter. When handleHardwareError is triggered by the controller, it calls hardwareErrorCallback(hardwareCode) which throws TypeError: hardwareErrorCallback is not a function, crashing the Node.js process.
Impact
Any BLE hardware error event from the controller — which can occur due to firmware issues, signal interference, or transient hardware faults — will unconditionally crash the entire Node.js application. The error recovery logic inside ble-manager.js (the onHardwareError handler passed via Adapter(transport, onHardwareError)) is completely bypassed and never executes.
Steps to Reproduce
- Use
BleManager.create() to initialise a BLE manager
- Trigger a Hardware Error HCI event from the controller (HCI event code
0x10), for example by inducing a firmware fault or observing it naturally on hardware prone to occasional hardware error events (e.g. Raspberry Pi built-in Bluetooth)
- Observe the process crash with
TypeError: hardwareErrorCallback is not a function
Fix
One-line change in lib/internal/adapter.js:
module.exports = function(transport, hardwareErrorCallback) {
return new HciAdapter(transport, hardwareErrorCallback);
};
When the BLE controller emits a Hardware Error HCI event, the process crashes with:
I beleive the root cause is a missing parameter in the module export at the bottom of
lib/internal/adapter.js. ThehardwareErrorCallbackargument is accepted byHciAdapterinternally but is never forwarded from the exported factory function:As a result,
hardwareErrorCallbackis alwaysundefinedinsideHciAdapter. WhenhandleHardwareErroris triggered by the controller, it callshardwareErrorCallback(hardwareCode)which throwsTypeError: hardwareErrorCallback is not a function, crashing the Node.js process.Impact
Any BLE hardware error event from the controller — which can occur due to firmware issues, signal interference, or transient hardware faults — will unconditionally crash the entire Node.js application. The error recovery logic inside
ble-manager.js(theonHardwareErrorhandler passed viaAdapter(transport, onHardwareError)) is completely bypassed and never executes.Steps to Reproduce
BleManager.create()to initialise a BLE manager0x10), for example by inducing a firmware fault or observing it naturally on hardware prone to occasional hardware error events (e.g. Raspberry Pi built-in Bluetooth)TypeError: hardwareErrorCallback is not a functionFix
One-line change in
lib/internal/adapter.js: