Skip to content

Fix: Windows connects to the Octatrack where it never could (new USB revision) - #1476

Closed
repeat98 wants to merge 5 commits into
mainfrom
fix/windows-winusb-rev
Closed

repeat98 wants to merge 5 commits into
mainfrom
fix/windows-winusb-rev

Conversation

@repeat98

@repeat98 repeat98 commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Draft: waits for one Windows test (below). Base regenerated, pr:ready Ready.

  • What was wrong: on some Windows computers the site never connects to the Octatrack and says "Modwerk is open in another tab or browser…", even with no other tab or browser open. A member reported it on the site (Windows, Edge and Brave alike). Opt-in diagnostics show the same pattern on another Windows computer (repeated claim-failed, never connected), while other Windows computers connect fine.
  • Cause, from the reporter's edge://device-log: the composite device enumerates (usbccgp), the audio interfaces bind usbaudio, but for the vendor interface Edge logs Failed to parse device interface GUID: (empty) and Interface 1 has no device path. So claimInterface fails, and OctatrackLink.claim() maps every claim failure to busy and LINK_BUSY. On a working Windows dev unit the same interface (USB\VID_1935&PID_0002&MI_01) has service WINUSB and DeviceInterfaceGUIDs = {4DEA1B9D-6B51-400A-93C9-5CFFC5DF8CF1} from the base's MS OS 2.0 set (usb_base.py msos20(), unchanged since 10 Oct). Windows writes that registry property only when it installs an interface, so a computer that set up interface 1 without it keeps an interface WebUSB can't open. What set it up that way on the affected computer is unknown (octabam's firmware sends no Windows descriptors).
  • What this changes:
    • The base's device descriptor reports bcdDevice 0x0101 (BASE_REVISION) instead of stock's 0x0001. A changed revision changes every interface's hardware ID (…&REV_0101&MI_01) and the key of Windows' per-device USB cache (usbflags\19350002xxxx), which should make Windows set the interfaces up again from the MS OS 2.0 set, GUID included, with nothing for the musician to do. WebUSB permission (VID/PID/serial) and Windows' device instance (serial-based) keep their identity. Fallback if the revision isn't enough: a new serial number (a certain fresh setup, but everyone picks the unit in the USB picker once).
    • Base regenerated (npm run octatrack:base -- --stock … --beta --write): identity 87258f15… (was 4854b76c…); browser .bin = build_core.py .bin 25e1bbf7…, 782,340 bytes. The descriptor test now requires the new revision and stock's bytes everywhere else.
    • Base-bound packages restamped for 87258f15… (npm run octatrack:module-packages): Output Matrix, CC Map, Recorder Loop Fix, Analog BD; no package bytes changed. Sidechain 0.2.1 is held, so the tool skips it: its requiredBase is set by hand, after the base build printed its sha fd275bf2…, the committed bytes.
    • The busy line: on Windows it adds "If nothing else is open, install the latest base from the card once, and this computer connects from then on." (linkBusy(), the same user-agent split as openFailure()). The rest of the line no longer says another tab is certainly the cause.
    • Changelog: changelog/2026-11-12-windows-usb-reconnect.md.
  • Dropped from the earlier plan: gating the line on navigator.locks.query() can't work: the claim runs while this tab holds the USB lock, and another browser or profile never shows up in this profile's locks. Sending the claim error's name with claim-failed adds nothing: Chromium rejects every failed claim with the same NetworkError ("Unable to claim interface."), whether the interface has no device path or another browser holds it.

The Windows test (resume here)

The build folder is on the owner's Mac, outside Git: ~/.cache/modwerk-local/ot/winusb-rev/beta. Rather than rebuild on the Windows PC, RAM-boot the unit from the Mac and move the cable: the Octatrack has its own power, so a RAM boot survives the move.

  1. Break it on purpose. Unit on its flashed base, plugged into the Windows dev PC, the site connecting. In an admin terminal: reg query "HKLM\SYSTEM\CurrentControlSet\Enum\USB\VID_1935&PID_0002&MI_01" /s /v DeviceInterfaceGUIDs (note the key and value), then reg delete "<that key>" /v DeviceInterfaceGUIDs /f. Replug. Expected: pnputil /enum-interfaces /class {4DEA1B9D-6B51-400A-93C9-5CFFC5DF8CF1} lists nothing, edge://device-log shows the two errors above, and the site shows the busy line.
  2. Boot the fix. Cable to the Mac: npm run device -- boot ~/.cache/modwerk-local/ot/winusb-rev/beta (RAM boot, no flash).
  3. Back to Windows. Expected: Windows sets the device up again, reg query shows the GUID, pnputil lists the interface, and the site connects to base 87258f15…. If not, restore the value (reg add "<key>" /v DeviceInterfaceGUIDs /t REG_MULTI_SZ /d "{4DEA1B9D-6B51-400A-93C9-5CFFC5DF8CF1}" /f) and the fallback is a new serial number.
  4. Power cycle (the flashed base, revision 0x0001, comes back) and plug into Windows again. Note whether the site still connects: it tells whether the repaired setup stays with the device or flips back with the revision.

After a pass: add the Windows trap line to docs/OCTATRACK_HARDWARE_TRAPS.md, mark ready, merge; base release steps as usual. An affected member can't take a USB base update, so they install the new base from the card once (what the new line says).

How I checked it

  • npm run pr:ready: Ready, after merging main (run without the local dsp_asm, as CI does: with it, test_resident_engines fails 1004≠1009 as it does on main, and dsp_packages --check stops on a KeyError modulation from the local octabam checkout; this branch touches neither).
  • test_recipe.py descriptor test and octatrack-link.test.ts / BaseInstallDialog.guide.test.ts pass.
  • Not tested on a unit: no Octatrack on this Mac's USB, and no Windows computer here.

What the guides lacked or got wrong

docs/OCTATRACK_HARDWARE_TRAPS.md (USB and EP0) says Windows binds WinUSB by itself, but not that Windows keeps an interface's first setup. To add once the Windows test confirms the remedy.

🤖 Generated with Claude Code

…vice

Windows applies the Microsoft OS 2.0 registry property (DeviceInterfaceGUIDs)
only when it installs an interface. A Windows computer whose interface 1 was
set up without it keeps no device path, so WebUSB's claimInterface fails and
the site shows its 'another tab' line. A new revision (0x0101) should make
Windows set the interfaces up again. Draft: not yet tested on a unit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the bug Something isn't working label Nov 12, 2026
repeat98 and others added 4 commits November 12, 2026 17:13
…names the computer on Windows

The base reports bcdDevice 0x0101: regenerated with --beta --write (browser .bin =
build_core.py .bin 25e1bbf7). The descriptor test now requires the new revision and
stock's bytes elsewhere. On Windows the busy line adds: install the latest base from
the card once (a computer that set up the vendor interface without its GUID can't
claim it, with the same NetworkError as a busy unit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
octatrack:module-packages restamped four; Sidechain 0.2.1 is held, so its
requiredBase is set by hand (the base build printed its sha fd275bf2, the committed bytes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@repeat98

Copy link
Copy Markdown
Owner Author

Closed into #1502: all changes that need a new Octatrack base go out as one base update. This branch is merged there with its commits, and its description and test notes are carried over.

@repeat98 repeat98 closed this Nov 13, 2026
ex1010 pushed a commit to ex1010/modwerk that referenced this pull request Nov 13, 2026
…vision repairs it

The Windows test repeat98#1476 still owed, run on the owner's PC on 13 November 2026:
a missing DeviceInterfaceGUIDs breaks the connection and survives a replug;
the unit arriving with another bcdDevice writes it back.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant