Skip to content

fix: improve error handling in device flow CLI and OAuth callback #84

@rorybyrne

Description

@rorybyrne

Three related error-handling gaps in the device flow, all resulting in confusing UX when things go wrong.

1. resp.json() unguarded in _poll_for_token

File: sdk/py/osa/cli/login.py (lines 56, 65)

Both the 200 and 400 response paths call resp.json() without exception handling. A non-JSON body from a WAF or proxy raises json.JSONDecodeError, which propagates unhandled and crashes osa login with a traceback instead of a friendly error message.

2. Device flow users routed to frontend on early OAuth errors

File: server/osa/application/api/v1/routes/auth.py (lines 191–202)

The if error: and if not state: early exits redirect to {frontend_url}/auth/error before is_device_flow is determined. If a user clicks "Deny" on ORCID during a device flow, they see the frontend app error page (not the device-specific page that says "return to your terminal"). The state parameter, which identifies the session as a device flow, is available in the OAuth error redirect but isn't parsed before the early return.

3. Hardcoded "Device code expired" for all failure modes

File: sdk/py/osa/cli/login.py (line 139)

When _poll_for_token returns None, the CLI always prints "Device code expired. Please try again." — but None is also returned for server errors like device_not_found or device_consumed, misleading users about the actual failure reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglow-priorityNice to have, no rush

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions