Skip to content

show actionable fix when USB device access is denied on Linux#215

Open
itsdestin wants to merge 1 commit into
commaai:masterfrom
itsdestin:linux-access-denied
Open

show actionable fix when USB device access is denied on Linux#215
itsdestin wants to merge 1 commit into
commaai:masterfrom
itsdestin:linux-access-denied

Conversation

@itsdestin

Copy link
Copy Markdown

Problem

On Linux, /dev/bus/usb device nodes are typically root-owned with mode 0664 (no write access for regular users — stock behavior on Arch and others). Chrome can enumerate the device, so it appears in the WebUSB picker and every wizard step passes, but USBDevice.open() then throws SecurityError: Access denied. and flashing fails instantly.

Today that surfaces as a generic LOST_CONNECTION ("Lost connection… Did you forget to unbind the device from qcserial?") — which misdirects users who did unbind. We lost a while to cable/port/USB-speed theories before tracing it to permissions. Reports like #192 (error 4, console shows Connection error {}, no resolution) suggest this conflation is generating undiagnosable bug reports.

Verified on CachyOS (Arch-based), Chrome 148, comma 3X: the failure was instant and identical across cables, ports, and USB 2/3 enumeration; sudo chmod 666 on the device node, with no other change, made the very next attempt flash to completion.

Change

  • manager.js: new ErrorCode.ACCESS_DENIED, detected in #connect() by walking the error cause chain for SecurityError (qdl.js preserves the original DOMException as cause). All other connect failures still map to LOST_CONNECTION.
  • Flash.jsx: dedicated error screen for ACCESS_DENIED. On Linux it shows a copyable one-time fix — a udev rule using TAG+="uaccess" (the approach recommended by Chromium developers), covering both 05c6:9008 (comma 3/3X) and 3801:9008 (comma four). On non-Linux platforms (e.g. Windows, where SecurityError usually means another program holds the device) it shows a generic message.
  • manager.test.js: unit tests for the detection (direct SecurityError, wrapped as cause, negative cases).

Precedent: commaai/openpilot#34674 added the equivalent udev rule for panda DFU mode.

An alternative/complementary approach would be adding the udev rule to the Linux "Unbind" wizard step so the error never happens — happy to extend this PR that way if preferred.

Verification

  • bun run build passes
  • vitest run src/utils/manager.test.js — 3/3 pass
  • Full suite: stream.test.js passes; manifest.test.js fails identically on unmodified master (live manifest has 32 images vs expected 33 — unrelated)

🤖 Generated with Claude Code

On Linux, /dev/bus/usb device nodes are typically root-owned without
group write access, so USBDevice.open() throws SecurityError ('Access
denied.') and flashing fails instantly. This was previously reported as
generic LOST_CONNECTION with a hint blaming qcserial, which misdirects
users who already unbound it.

Detect the SecurityError (preserved as the error cause by qdl.js) and
show a dedicated error screen with a copyable one-time udev rule fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant