Summary
A fresh install with a normal macOS setup shows no devices in the GUI, with
zero diagnostic output explaining why. Root cause turned out to be a
missing Input Monitoring privacy grant to the background agent — a
permission that is (a) separate from Accessibility, (b) never requested or
prompted, and (c) undocumented. Compounding it, the launchd-managed agent
runs with no log redirection, so its failed to open HID++ channel
warnings go nowhere — the user has no way to discover the cause without
running the binary by hand with OPENLOGI_LOG=debug.
Filing this so the next person doesn't spend an hour guessing.
Environment
- macOS 15 (darwin 25.5.0, arm64)
- Devices: MX Master 3S + MX KEYS S, both paired Bluetooth-direct
(BLE) — no Logi Bolt/Unifying receiver, nothing wired
- Logi Options+: not installed (so receiver contention is ruled out)
- OpenLogi 0.6.18 via Homebrew cask
- Accessibility: granted to OpenLogi Agent
Symptom
GUI opens, but the device carousel is empty — neither device appears, so no
buttons can be configured. Both devices are connected to the Mac over
Bluetooth (confirmed in System Settings → Bluetooth). No error, no prompt,
nothing in any log.
Root cause (two layered problems)
1. Missing Input Monitoring grant (the actual blocker)
OpenLogi's device discovery (openlogi_hid::transport::enumerate_hidpp_devices)
does see BLE-direct devices — the debug log shows them matching the
0xFF43 / 0x0202 HID++ long-report collection:
DEBUG logitech HID node name=MX Master 3S pid=b034 usage_page=0xff43 usage_id=0x0202 matched=true
DEBUG logitech HID node name=MX KEYS S MAC pid=b37c usage_page=0xff43 usage_id=0x0202 matched=true
DEBUG HID++ candidate interfaces count=2
WARN failed to open HID++ channel — retrying next tick error=Message("Failed to open device")
WARN failed to open HID++ channel — retrying next tick error=Message("Failed to open device")
Enumeration works; the IOHIDDeviceOpen call fails for both, every 2s tick,
with "Failed to open device". On macOS under the Hardened Runtime, that
maps to a denied TCC grant — specifically Input Monitoring
(kTCCServiceListenEvent), which gates reading raw HID device input. This is
a separate permission from Accessibility (kTCCServiceAccessibility), so
granting Accessibility (which the agent prompts for and the README/setup flow
covers) does nothing for device discovery. After toggling Input Monitoring on
for OpenLogi Agent and restarting, both devices enumerate and the GUI
works:
DEBUG opened HID++ channel name=MX Master 3S vid=046d
DEBUG opened HID++ channel name=MX KEYS S MAC vid=046d
Notably, nothing in OpenLogi ever requests the Input Monitoring grant or
tells the user it's needed — there's no prompt, no settings hint, and the
agent's accessibility prompt at startup (Hook::prompt_accessibility) only
covers the event-tap permission.
2. The launchd agent has no log redirection (why it's invisible)
The agent is managed by a launchd plist
(~/Library/LaunchAgents/org.openlogi.agent.plist) generated by
crates/openlogi-agent/src/launch_agent.rs. That plist has no
StandardOutPath / StandardErrorPath keys, so when launchd runs the
agent, every tracing line — including the very failed to open HID++ channel
warnings that would have explained this — is discarded. The user only sees
them by manually stopping the agent and running the binary foreground:
OPENLOGI_LOG=debug /Applications/OpenLogi.app/Contents/Library/LoginItems/OpenLogiAgent.app/Contents/MacOS/openlogi-agent
This is what made the bug a guessing game instead of a one-line diagnosis.
Suggested improvements (rough ideas, not prescriptive)
- Detect + prompt for Input Monitoring. On macOS, when enumeration
finds Logitech HID nodes that then fail to open, surface a UI hint (and/or
a CGPreflightListenEventAccess/CGRequestListenEventAccess-style prompt)
pointing to System Settings → Privacy & Security → Input Monitoring —
analogous to how Accessibility is already prompted for.
- Persist agent logs. Add
StandardOutPath/StandardErrorPath to the
generated launchd plist (e.g. to a file under the data dir or
~/Library/Logs/openlogi/), so the existing tracing warnings are
actually observable. The OPENLOGI_LOG=debug transport-level log line at
crates/openlogi-hid/src/transport.rs (the logitech HID node ... matched=
debug) is purpose-built for exactly this diagnosis — it just needs to land
somewhere readable.
- README mention that Bluetooth-direct devices need the Input Monitoring
grant, since it's not obvious that device pairing (Bluetooth) and device
control (HID++ open) are separately permissioned.
Happy to take a swing at any of these if there's a preferred direction —
especially #2 (the launchd log redirection) since it's small and purely
additive.
Workaround for anyone hitting this now
- System Settings → Privacy & Security → Input Monitoring → enable
OpenLogi Agent (the binary at
OpenLogi.app/Contents/Library/LoginItems/OpenLogiAgent.app; it's not in
/Applications, so you may need to drag it from Finder or add by path).
- Also enable OpenLogi (the GUI) there for good measure.
- Quit and reopen OpenLogi (a TCC grant requires a process restart).
(Adding the agent to Input Monitoring is awkward because it lives nested
inside the .app bundle and macOS's "+" picker won't let you browse into a
bundle — drag-and-drop from Finder, revealed via
open -R /Applications/OpenLogi.app/Contents/Library/LoginItems/OpenLogiAgent.app,
works.)
Summary
A fresh install with a normal macOS setup shows no devices in the GUI, with
zero diagnostic output explaining why. Root cause turned out to be a
missing Input Monitoring privacy grant to the background agent — a
permission that is (a) separate from Accessibility, (b) never requested or
prompted, and (c) undocumented. Compounding it, the launchd-managed agent
runs with no log redirection, so its
failed to open HID++ channelwarnings go nowhere — the user has no way to discover the cause without
running the binary by hand with
OPENLOGI_LOG=debug.Filing this so the next person doesn't spend an hour guessing.
Environment
(BLE) — no Logi Bolt/Unifying receiver, nothing wired
Symptom
GUI opens, but the device carousel is empty — neither device appears, so no
buttons can be configured. Both devices are connected to the Mac over
Bluetooth (confirmed in System Settings → Bluetooth). No error, no prompt,
nothing in any log.
Root cause (two layered problems)
1. Missing Input Monitoring grant (the actual blocker)
OpenLogi's device discovery (
openlogi_hid::transport::enumerate_hidpp_devices)does see BLE-direct devices — the debug log shows them matching the
0xFF43 / 0x0202HID++ long-report collection:Enumeration works; the
IOHIDDeviceOpencall fails for both, every 2s tick,with
"Failed to open device". On macOS under the Hardened Runtime, thatmaps to a denied TCC grant — specifically Input Monitoring
(
kTCCServiceListenEvent), which gates reading raw HID device input. This isa separate permission from Accessibility (
kTCCServiceAccessibility), sogranting Accessibility (which the agent prompts for and the README/setup flow
covers) does nothing for device discovery. After toggling Input Monitoring on
for OpenLogi Agent and restarting, both devices enumerate and the GUI
works:
Notably, nothing in OpenLogi ever requests the Input Monitoring grant or
tells the user it's needed — there's no prompt, no settings hint, and the
agent's accessibility prompt at startup (
Hook::prompt_accessibility) onlycovers the event-tap permission.
2. The launchd agent has no log redirection (why it's invisible)
The agent is managed by a launchd plist
(
~/Library/LaunchAgents/org.openlogi.agent.plist) generated bycrates/openlogi-agent/src/launch_agent.rs. That plist has noStandardOutPath/StandardErrorPathkeys, so when launchd runs theagent, every
tracingline — including the veryfailed to open HID++ channelwarnings that would have explained this — is discarded. The user only sees
them by manually stopping the agent and running the binary foreground:
This is what made the bug a guessing game instead of a one-line diagnosis.
Suggested improvements (rough ideas, not prescriptive)
finds Logitech HID nodes that then fail to open, surface a UI hint (and/or
a
CGPreflightListenEventAccess/CGRequestListenEventAccess-style prompt)pointing to System Settings → Privacy & Security → Input Monitoring —
analogous to how Accessibility is already prompted for.
StandardOutPath/StandardErrorPathto thegenerated launchd plist (e.g. to a file under the data dir or
~/Library/Logs/openlogi/), so the existingtracingwarnings areactually observable. The
OPENLOGI_LOG=debugtransport-level log line atcrates/openlogi-hid/src/transport.rs(thelogitech HID node ... matched=debug) is purpose-built for exactly this diagnosis — it just needs to land
somewhere readable.
grant, since it's not obvious that device pairing (Bluetooth) and device
control (HID++ open) are separately permissioned.
Happy to take a swing at any of these if there's a preferred direction —
especially #2 (the launchd log redirection) since it's small and purely
additive.
Workaround for anyone hitting this now
OpenLogi Agent (the binary at
OpenLogi.app/Contents/Library/LoginItems/OpenLogiAgent.app; it's not in/Applications, so you may need to drag it from Finder or add by path).(Adding the agent to Input Monitoring is awkward because it lives nested
inside the
.appbundle and macOS's "+" picker won't let you browse into abundle — drag-and-drop from Finder, revealed via
open -R /Applications/OpenLogi.app/Contents/Library/LoginItems/OpenLogiAgent.app,works.)