Blog
OAuth Device-Code Errors in a CLI Login
Device-code login fails in ways browser OAuth does not: expired codes, the wrong verification URL, and a poll that gives up. Give each case a code. Developers will not describe a spinner.
2026-10-09 · 7 min read · AethelLayer
The spinner is not an error message
Device code flow (RFC 8628) asks a developer to open a URL and type a code while the CLI polls. When it fails, the terminal often says 'login timed out' after they already finished the browser step. They do not know whether the code expired, the poll hit authorization_pending too long, or the token request was rejected.
Those are different fixes. Expiry means show a longer code lifetime or a clearer countdown. A rejected token means the client id or audience is wrong. A timeout means your poll interval or their network.
Map the OAuth errors to your codes
authorization_pending and slow_down are not user errors. Keep polling, and slow down when told. expired_token, access_denied, and an invalid client are user-visible. Print your stable code plus the provider's error string.
Never print the device code's secrets twice, and do not send the access token in a probe. The failure code and the verification host are enough.
Staging is where this breaks
Evaluators pass --env staging and then open the production verification URL you printed by default. The code is valid in the wrong authorization server. Name the environment in the URL you print, and in the error if the token endpoint host does not match the flag.
Capture that mismatch. A week of 'I was trying to log in to staging' against a production host is a one-line bug in the CLI, and you will not hear it from people who quietly switch tools.
Draft the issue with the step they reached
Record whether you had issued a device code, whether the browser step was acknowledged, and which error ended the poll. Reviewers can tell a docs problem from an IdP outage.
A human still sends the GitHub issue. Device-code logs are close to credentials. Treat the draft as sensitive until someone checks it.
Keep reading
Capture the failure before they leave
Capture the failure before they leave. Book early access or talk to sales, then install @aethellayer/sdk when you are onboarded.