SSO login button silently swallows 5xx / CORS / network errors from `getUserSSOUrl()`
- Dominant language
- TypeScript
- Stars
- 156k
- Forks
- 24.6k
- Avg merge
- 22h 9m
- Merged PRs (30d)
- 610
Description
### Self Checks
- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.
### Dify version
web/main (uncommitted)
### Cloud or Self Hosted
Self Hosted (Source)
### Steps to reproduce
Discovered by peaks-loop code-sweep on 2026-07-02.
1. Configure SSO for a tenant (SAML / OIDC / OAuth2 — all three providers share the bug).
2. Misconfigure the SSO endpoint so it returns 5xx or triggers a CORS preflight failure (e.g. wrong `SSO_REDIRECT_URL` allow-list, or simulate with DevTools "Block request URL").
3. Click the SSO login button on `/signin`.
4. The button enters the loading state, then... stays loading forever. No toast appears. The user has no idea whether the SSO attempt failed or is still pending.
### ✔️ Expected Behavior
SSO login attempts that fail at the network layer (5xx, CORS, DNS failure) must surface a user-visible error toast so the user knows the login attempt failed and the button re-enables for retry. The translation key `error.ssoFailed` should be added to the i18n bundle.
### ❌ Actual Behavior
The SSO login button at `web/app/signin/components/sso-auth.tsx` chains `getUserSSOUrl(...).then(...).finally(...)` for all three protocols (SAML, OIDC, OAuth2). When the network call rejects — e.g. enterprise SSO endpoint misconfigured, CORS error, server 5xx — the rejection is silently swallowed by `.finally()` and the UI just stays in the loading state with no user feedback.
**Proposed change:**
- In `web/app/signin/components/sso-auth.tsx`: add a `.catch()` before `.then().finally()` that emits a `toast.error(t('error.ssoFailed'))` so the user knows the login attempt failed and the button re-enables.
- In `web/i18n/en-US/login.json`: add a new `error.ssoFailed` key (other locales will be resynced by the i18n:check workflow).
**Risk:** The happy path (`res?.url` defined → `location.href = res.url`) is unchanged. The `finally` block still resets `setIsLoading(false)` so the button re-enables for retry. No backend, schema, controller, or frontend changes outside the touched file.
Sister fix: PR #38336 (check-code email login errors).
Contributor guide
Research direction
Start in web/app/signin/components/sso-auth.tsx and inspect the getUserSSOUrl(...).then(...).finally(...) flows for SAML, OIDC, and OAuth2. Check web/i18n/en-US/login.json for the error namespace, then verify that rejected requests show the new error.ssoFailed toast and that the loading state resets for retry; run the i18n:check workflow if available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, internationalization
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100