Skip to content

Fix intermittent "Cannot find footswitch" on macOS#106

Merged
rgerganov merged 1 commit into
rgerganov:masterfrom
titan550:fix-macos-interface-select
Jun 24, 2026
Merged

Fix intermittent "Cannot find footswitch" on macOS#106
rgerganov merged 1 commit into
rgerganov:masterfrom
titan550:fix-macos-interface-select

Conversation

@titan550

@titan550 titan550 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Human Note

I kept getting this error randomly even when the USB pedal was plugged in.

❯ ./footswitch -r
Cannot find footswitch with one of the supported VID:PID.
Check that the device is connected and that you have the correct permissions to access it. [init(), src/footswitch.c:111]

This patch fixed the issue for me.

Problem

On macOS, footswitch intermittently fails with:

Cannot find footswitch with one of the supported VID:PID.

even though the device is connected and visible to the system (ioreg /
hidutil both show it). A reboot "fixes" it for a while, then it comes back.

Root cause

The macOS branch of init_pid() opened the device with
hid_open(vid, pid, NULL), which opens whichever HID interface hidapi
enumerates first. The pedal is a composite device:

  • interface 0 — keyboard/mouse, which macOS refuses to let an
    unprivileged process open (IOHIDDeviceOpen returns kIOReturnNotPermitted,
    0xE00002E2)
  • interface 1 — the vendor interface that carries the config protocol

hidapi's macOS enumeration order isn't stable, so when interface 0 came
first, hid_open() tried it, was denied, and returned NULL → "Cannot find
footswitch". A reboot just reshuffled the order, which is why the failure
seemed to come and go.

Fix

Use the interface_number == 1 selection that the non-OSX path already used,
for all platforms. A macOS-only fallback to the previous
hid_open(vid, pid, NULL) is kept for older hidapi (<0.14) that doesn't
report interface_number on macOS, so existing setups are unaffected.

Testing

  • macOS 26.4.1 (arm64), hidapi 0.15.0 (Homebrew): footswitch -r now reads
    reliably, including across unplug/replug cycles that previously triggered
    the failure.
  • Builds clean (make, -Wall).
  • Linux path is unchanged: the fallback is #ifdef OSX, and the libusb
    backend has always reported interface_number.

Notes

scythe.c, scythe2.c, and footswitch1p.c use the same bare hid_open()
pattern and likely share this latent issue on composite devices (possibly
related to #60). Left out to keep this PR focused — happy to follow up.

On macOS the device was opened with hid_open(vid, pid, NULL), which opens
whichever HID interface hidapi enumerates first. The pedal is a composite
device: interface 0 is the keyboard (which macOS refuses to let an
unprivileged process open) and interface 1 carries the config protocol.
When the keyboard interface enumerated first, the open was denied and the
tool printed "Cannot find footswitch ..." -- intermittently, until a reboot
reshuffled the enumeration order.

Select interface 1 explicitly on all platforms, which is what the non-OSX
path already did. Keep a macOS-only fallback to hid_open() for older hidapi
(<0.14) that doesn't report interface_number on macOS, so existing setups
keep working.

Tested on macOS 26.4.1 (arm64) with hidapi 0.15.0: footswitch -r now reads
reliably across unplug/replug cycles that previously triggered the failure.
@titan550
titan550 marked this pull request as ready for review June 24, 2026 07:07

@rgerganov rgerganov left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not able to this on a MacOS device at the moment but the root cause analysis sounds reasonable and the patch looks good.

@rgerganov
rgerganov merged commit 454e00b into rgerganov:master Jun 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants