Skip to content

fix: report a rejected PKCE token exchange as an auth error (FLYTE-SDK-7D) - #1432

Open
EngHabu wants to merge 2 commits into
mainfrom
fix/sentry-7d-pkce-token-error
Open

fix: report a rejected PKCE token exchange as an auth error (FLYTE-SDK-7D)#1432
EngHabu wants to merge 2 commits into
mainfrom
fix/sentry-7d-pkce-token-error

Conversation

@EngHabu

@EngHabu EngHabu commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Why

FLYTE-SDK-7Dflyte run against a deployment whose OAuth2 application is misconfigured.

Reading the whole exception chain rather than the reported title, the event holds two independent problems. The ConnectError: invalid content-type: 'text/html' half is already handled by #1411 (merged yesterday; the event is from release 2.5.18, which predates it). This PR is the other half:

RuntimeError: Failed to request access token with response: [400]
b'{\n  "error": "invalid_request",\n  "error_description": "client_secret is missing."\n}'
  flyte/remote/_client/auth/_authenticators/pkce.py  _request_access_token

The identity provider is telling us the OAuth2 application backing browser login is registered as a confidential client and wants a client_secret the PKCE flow doesn't send. That is a deployment configuration problem, but a bare RuntimeError is unclassified, so:

  • it escaped to Sentry as if it were an SDK crash, and
  • the user saw a Python bytes repr instead of the one sentence that explains the failure.

_token_client.get_token already raises AuthenticationError for the identical condition (_token_client.py:157) — the PKCE authorization client simply never got the same treatment.

What

  • _request_access_token raises AuthenticationError instead of RuntimeError on a non-200 from the token endpoint. AuthenticationError is on _sentry._is_user_error's allow-list, so it stops being crash-reported, and it still subclasses RuntimeError, so no caller changes.
  • Decode the RFC 6749 §5.2 error body (error, error_description, error_uri) rather than dumping raw bytes. Non-JSON bodies — an HTML page from a proxy answering the token endpoint — are quoted and truncated to 200 chars.
  • The sibling Expected "access_token" in response from oauth server ValueError becomes an AuthenticationError for the same reason.

Before / after for the reported event:

RuntimeError: Failed to request access token with response: [400] b'{\n "error": "invalid_request",\n "error_description": "client_secret is missing."\n}'

AuthenticationError: The identity provider at https://.../oauth2/token rejected the login (400): invalid_request: client_secret is missing. This is a configuration problem with the OAuth2 application backing browser (PKCE) login, not something the Flyte SDK can retry; contact whoever administers your Flyte/Union deployment.

Deliberately not changed

The state-parameter mismatch (Unexpected state parameter [...] passed) stays a ValueError. It guards against a forged callback and a genuine SDK bug could also trip it, so it should keep reporting. A test pins that.

Testing

8 tests in tests/flyte/remote/test_pkce_token_request.py. 6 verified failing on main; the 2 that pass there are the controls (success path, state mismatch). tests/flyte/remote + tests/flyte/keyring + tests/flyte/test_sentry.py = 684 passed, plus one failure (test_retrieve_degrades_when_keyring_not_installed) that also fails on clean main in my sandbox.

fixes FLYTE-SDK-7D

…K-7D)

The authorization-code -> access-token exchange raised a bare RuntimeError
carrying the raw response bytes whenever the identity provider answered with
anything other than 200:

    RuntimeError: Failed to request access token with response: [400]
    b'{\n  "error": "invalid_request",\n  "error_description":
    "client_secret is missing."\n}'

That is a deployment configuration problem -- the OAuth2 application backing
browser login requires a client secret that the PKCE flow does not send -- but
RuntimeError is unclassified, so it escaped to Sentry as an SDK crash and the
user got a Python bytes repr instead of an explanation.

`_token_client.get_token` already raises `AuthenticationError` for exactly this
condition (_token_client.py:157); the PKCE authorization client just never got
the same treatment. `AuthenticationError` is on `_sentry._is_user_error`'s
allow-list and still subclasses RuntimeError, so no caller changes.

Also decode the RFC 6749 section 5.2 error body -- `error`, `error_description`,
`error_uri` -- rather than dumping the raw bytes. The description is the only
part of the exchange that says why the login was rejected. Non-JSON bodies (an
HTML page from a proxy answering the token endpoint) are quoted and truncated.

The sibling `Expected "access_token" in response` ValueError becomes an
AuthenticationError for the same reason. The state-parameter mismatch check is
deliberately left as a ValueError: it guards against a forged callback, and a
genuine SDK bug could also trip it, so it should keep reporting.

fixes FLYTE-SDK-7D

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
@EngHabu EngHabu added the sentry-fix Fix for an issue surfaced by Sentry label Aug 13, 2026
Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sentry-fix Fix for an issue surfaced by Sentry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant