Repository navigation
fix: onboard finishes the sign-in when the token can't be saved, and the CLI says where it runs - #169
Merged
Conversation
bitpshr
added this pull request to stack #172
October 22, 2026 12:56
bitpshr
marked this pull request as ready for review
October 22, 2026 12:56
PaulAsjes
approved these changes
Oct 22, 2026
bitpshr
force-pushed
the
paul/onboard-server-error
branch
from
October 22, 2026 13:09
19ae814 to
c1f9a54
Compare
The token exchange can succeed while saving the token fails (a keychain that refuses the CLI, a sandboxed home folder). The browser then landed on the server_error page and the agent was told the sign-in didn't finish, even though onboard only needs the token for one account check. Keep the token in memory for that check, note the failed save in the worker log, and send the browser to the success page.
Also say plainly what a failed save leaves behind: commands that read the stored sign-in keep the old one, which may be another account's.
…luded; test the platform on the approval link
bitpshr
force-pushed
the
paul/onboard-server-error
branch
from
October 22, 2026 13:46
c1f9a54 to
1fbb6da
Compare
…hether a browser can reach the CLI
On Windows a clipboard read gives up after about 30 ms when another program has the clipboard open, and the sign-in then told the developer no key had been copied. The hand-off read now tries again for up to 2 s, which also covers a browser copy that lands late, and so does clearing the key once it is stored. A clipboard that never opens gets its own status, clipboard_unreadable, and the reply says the copied key may still be on the clipboard.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #167. It changes the hand-written sign-in that #167 adds.
Why
Some
onboardsign-ins end on theserver_errorpage even though the browser reached the CLI. From what I can tell there are two paths, and this PR fixes the first:server_hosted_mcp_oauth_grantedfires inside/v1/oauth/tokenafter a successful exchange. In 11 of the 24 onboardserver_errorpages since Oct 19 (8 people, mostly Mac), it fired 0.6–2 s before the error page. Once the exchange has worked, the only remaining step that can fail isactive_store().set(…). It probably fails because the Keychain refuses the binary: release builds aren't codesigned, so every upgrade counts as a new app for an existingelevenlabsentry. A sandboxed home folder would fail the same way.onboardonly uses that token for a singleGET /v1/usercheck, so failing the whole sign-in here is unnecessary.What changes
loopback::sign_inreturns the access token. If saving it fails, the reason goes to the worker log and the browser gets the success page.key_matches_sign_intakes the token directly instead of reading it back from the store.auth login(Fern's flow) is unchanged.One consequence: after a failed save, the key is in the env file and everything in
onboardworks, but commands that use the stored sign-in don't see this one. They keep whatever was stored before, so they may still act as the previous account.Also: where the CLI runs (folded in from #168)
From the API's side today, a CLI request is just
elevenlabs-cli/<version> cmd/<command>, so a problem like the Windows sign-in misses in #167 can't be told apart from WSL, containers or SSH. The hand-written commands now appendos/<windows|macos|linux|other>, plusenv/<ssh|container|wsl>when one applies, after theircmd/tag. Only whether the relevant environment variables are set is checked, and their values are never sent.onboardalso passescli_osandcli_envon the approval-page link. A sign-in whose callback never reaches the CLI makes no API call, so the page's events are the only place those misses can be counted per platform. SSH and container detection now lives in one place, a smallworkflow/platform.rs, which the browser check reuses. Its behavior is unchanged. The tag also counts Podman (/run/.containerenv) and Kubernetes pods (KUBERNETES_SERVICE_HOST), but the browser check doesn't: toolbox and distrobox are Podman containers that share the host's network and display, and telepresence copies a pod's environment onto a laptop. The xi side, which reads the tags on the backend and the link parameters on the page, is elevenlabs/xi#58352.Also: a sign-in that works but never checks the key
Some sign-ins reach the success page, but the CLI never sends its
GET /v1/usercheck. Since Oct 20 that's 8 of about 1,000 Windows hand-offs (7 people), against 1 of about 1,000 on Mac. None of them used the copied key: four made a new key by hand and ranonboard check, which is the manual path ("no key reached this command"), and one ranconnectagain 12 minutes later and it worked.From what I can tell it's the clipboard read. On Windows, arboard tries to open the clipboard six times, 5 ms apart, then gives up with
ClipboardOccupied, andonboardtreated that the same as nothing copied. Clipboard managers, remote desktop and sync tools hold the clipboard for short moments. (The other way to get here in 1.7.0, a token that couldn't be read back from the store, is already gone with the change above.)key_status,clipboard_unreadable, and says the copied key may still be on the clipboard, so the developer can paste it instead of creating another. An empty clipboard is stillno_key.One case this can't fix: Chromium's own clipboard write gives up just as quickly and fails silently, while the page still reports
key_copied. If that's what happened, the CLI reportsno_keyafter 2 s, as before.Testing
a_sign_in_the_credential_store_refuses_still_finishes: a file sits where the file store needs its folder, so the save fails. Without the fix the browser gets the exact production redirect (cli/error?error=server_error…). With it, the browser gets the success page and the worker finishes.a_clipboard_key_is_checked_with_the_token_the_sign_in_returned: the key check uses the tokensign_inreturns. It fails if the check reads the store again or sends a different token.onboard_test26/26 and bin 190/190 on this branch. No new clippy warnings. The new lines are rustfmt-clean (onboard/tests.rsandtests/onboard_test.rsalready had formatting differences, which I left alone). The Windows target type-checks.platform::detect_for,authorize_paramsand browser-reachability tests, thecommand_scopetests (the tag aftercmd/), and an onboard integration check that the approval link carries this machine'scli_os. That check fails if the link stops carrying it or reports the wrong OS.the_hand_off_read_waits_out_a_busy_or_late_clipboard(a busy clipboard then a key, a marker that lands late, never readable versus read but empty).clip_ofmaps arboard's errors (busy isUnreadable, no text isNothing), andoutcome_ofmapsUnreadabletoclipboard_unreadable. Not tested against a real held clipboard on Windows.Still open: the no-grant path
The error page records only
error, and the worker's reason stays in its log, so PostHog can't separate these cases. Timings (handoff to error page) fall into rough buckets: about 1 s (instant), about 2 s on Windows, 5.5 s on Linux every time (looks like DNS), and about 10.5 s (the 10 s connect timeout). The token URL isapi.us.elevenlabs.io, a different host from the rest of onboard, so a network or sandbox allowlist could block it alone. I haven't verified that. I think the next step is to send a coarse failure stage to the error page and record it, or check the backend logs forPOST /v1/oauth/token4xx at those times.