Skip to content

fix(auth): don't crash when no browser can be opened - #393

Merged
cvince merged 1 commit into
mainfrom
fix/open-browser-no-crash
Oct 15, 2026
Merged

cvince merged 1 commit into
mainfrom
fix/open-browser-no-crash

Conversation

@cvince

@cvince cvince commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Problem

On a machine with no browser launcher (a VM, a container, a server over SSH), capy login printed ✓ Opened browser for authentication and then crashed:

Error: spawn xdg-open ENOENT
  ... Unhandled 'error' event

The open package starts xdg-open and returns right away; the "not found" arrives a tick later as an error event with no listener, which Node treats as fatal. The surrounding try/catch had already returned, so it never caught it. The printed login link was never usable.

Fix

  • openScreen attaches an error listener to every process it starts and returns opened: boolean (read from pid, which Node leaves unset when a spawn fails).
  • Login prints ✓ Opened browser for authentication only when the browser actually opened. Otherwise it prints nothing extra: the link is already on screen and the callback server keeps waiting.

Verification

  • New tests in tests/ui/openScreen.test.ts cover a missing launcher (failing exactly the way Node reports it), the app-window fallback, a launcher that throws, a launcher that starts, and suppressed mode.
  • Full suite: 2408 pass, 0 fail. Typecheck clean.
  • Under real Node in a Linux VM with no xdg-open on PATH: the old code crashes with Unhandled 'error' event; the fixed code returns {"via":"default-browser","opened":false} and the process keeps running.

On a machine without a browser launcher (a VM, a container, a server
over SSH) login printed "Opened browser" and then died with an
unhandled 'error' event from spawning xdg-open, so the printed link
could never be used.

- openScreen now attaches an error listener to every launched process
  and reports whether it actually started (`opened`).
- Login only prints "Opened browser" when it did; otherwise the link
  already on screen is the way in, and the callback keeps waiting.
@cvince
cvince merged commit 2e39072 into main Oct 15, 2026
5 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.

1 participant