Skip to content

fix(auth): tell a refused Keychain apart from a missing login - #43

Merged
pfriedrix merged 1 commit into
masterfrom
fix/keychain-refusal-not-a-missing-login
Aug 8, 2026
Merged

fix(auth): tell a refused Keychain apart from a missing login#43
pfriedrix merged 1 commit into
masterfrom
fix/keychain-refusal-not-a-missing-login

Conversation

@pfriedrix

@pfriedrix pfriedrix commented Aug 8, 2026

Copy link
Copy Markdown
Owner
  • lcc openn answered "Not authenticated. Run lcc auth first." while the token sat in the Keychain, valid, and then exited the process, taking every other session's row down with the picker. oauth.readToken now separates nothing stored from the Keychain refused the read (naming the OSStatus, via a keychain.describeLast that nothing had ever called) and from a stored value that will not parse; start.bail returns error.Failed instead of exiting when the dashboard is its caller.
  • The original refusal could not be reproduced here — the Keychain answers from every context tested: a plain call, an interactive dashboard in a pty, and a child the daemon spawned. So the fix is the diagnosis: the next occurrence names its own cause instead of sending the user through a browser round trip for a dialog that only had to be answered.

Pressing n on the lcc open dashboard answered "Not authenticated. Run
`lcc auth` first." while the token sat in the Keychain, valid, and then
took the dashboard down with it.

oauth.getToken collapsed three answers into one null: nothing stored, a
Keychain that refused the read, and a stored value that will not parse.
Only the first means the user has to authenticate. The refusal is the
likeliest of the three on a machine that rebuilds lcc, because a renewed
signing certificate changes the designated requirement and macOS asks
once more — a dialog that can be denied, escaped, or missed behind a
full-screen terminal. Sending that user through a browser round trip
fixes it only by accident. readToken separates the three, and
keychain.describeLast, which nothing had ever called, names the OSStatus
so the next occurrence is diagnosable from the one line it prints.

The second failure is that start.bail exited the process. lcc open runs
start.run in-process for n and catches its errors precisely so the
dashboard survives, so one bad answer ended every other session's row
along with the picker. bail now returns error.Failed under
returns_to_caller, the flag cancel already used for the same reason.
@pfriedrix
pfriedrix merged commit e17a6aa into master Aug 8, 2026
1 check passed
@pfriedrix
pfriedrix deleted the fix/keychain-refusal-not-a-missing-login branch August 8, 2026 16:07
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