Skip to content

fix(auth): recover from setup status timeouts - #4371

Merged
WillemJiang merged 3 commits into
bytedance:mainfrom
urzeye:fix/4366-auth-setup-timeout
Jul 26, 2026
Merged

fix(auth): recover from setup status timeouts#4371
WillemJiang merged 3 commits into
bytedance:mainfrom
urzeye:fix/4366-auth-setup-timeout

Conversation

@urzeye

@urzeye urzeye commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #4366

Why

When the Gateway accepts a connection but /api/v1/auth/setup-status does not respond, the client-side auth probe had no timeout. The setup page could therefore remain on Loading… indefinitely, while the login page could never resolve whether registration should be available.

The SSR auth probe already had a five-second timeout, so client and server behavior diverged precisely during first boot, database migrations, or Gateway/database outages. Users received no actionable error and, on setup, the previous fallback silently redirected them to login.

What changed

  • Client-side setup-status checks now use the same five-second timeout as SSR auth probes. Every request gets a fresh AbortSignal, and its timer is cleared on every completion path.
  • /setup now replaces infinite loading and silent redirects with a localized unavailable state. Users can retry the probe or continue to login.
  • /login remains usable when the setup probe fails. It displays a localized retry notice and conservatively hides registration until the setup state is known.
  • Retrying setup-status no longer refetches unrelated SSO provider configuration.
  • Registration remains hidden while setup-status is unavailable; existing users can still sign in.
  • Regression tests cover pending requests, timeout aborts, timer cleanup, HTTP failures, and fresh signals on retry.

Surface area

  • Frontend UI — page / component / setting / interaction under frontend/
  • Backend API — endpoint / SSE event / request-response shape under backend/app
  • Agents / LangGraph — agent node, graph wiring, langgraph.json, or prompt change
  • Sandboxdocker/ or sandboxed execution
  • Skills — change under skills/
  • Dependencies — new/upgraded entry in backend/pyproject.toml or frontend/package.json (say what it buys us)
  • Default behavior change — changes existing behavior without the user opting in (default model, default setting, data shape)
  • Docs / tests / CI only — no runtime behavior change

Screenshots / Recording

No recording is attached. Browser verification used intercepted setup-status responses to exercise both recovery paths:

  • /login: failure notice visible, login still enabled, registration hidden; retry success removes the notice and restores registration.
  • /setup: failure opens the unavailable state; retry success restores the administrator setup form.

Bug fix verification

  • Test path that reproduces the bug: frontend/tests/unit/core/auth/setup.test.ts
  • Did it go red on main and green on this branch? Not run as an isolated clean-main checkout. During implementation, the new regression suite failed before the timeout helper existed and passes on this branch.
  • Page-level component tests were not cheap because the frontend unit suite has no DOM/component-rendering harness. The visible recovery behavior was instead verified in a real Chromium session with the setup-status request forced to fail and then succeed on retry.

Validation

  • pnpm --dir frontend check
  • pnpm --dir frontend format
  • pnpm --dir frontend test — 81 test files, 723 tests passed
  • pnpm --dir frontend build
  • Browser verification in Chromium for failure and successful retry on both /setup and /login

AI assistance

Tool(s) used: Codex

How you used it: Implemented the timeout and recovery states, added regression tests, ran static/build/test validation, and exercised the UI recovery paths in Chromium.

  • I've read and understand every line of this change and take responsibility for it — it's not unreviewed AI output.

@github-actions github-actions Bot added area:frontend Next.js frontend under frontend/ risk:high High risk: backend API, agents, sandbox, auth, deps, CI size/M PR changes 100-300 lines labels Jul 22, 2026

@willem-bd willem-bd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General note (not tied to a specific line): fetchSetupStatus's new AbortController only fires on the 5s timeout — it doesn't abort in-flight requests on component unmount or on a retry. The original code behaved the same way, so this isn't a regression, and it's safe in practice: the cancelled flag prevents stale state writes and the 5s timeout bounds any lingering request.

That said, the abort infrastructure is now in place, so if you want to go a step further you could thread an AbortController from each effect's cleanup so requests cancel genuinely on navigation/retry. Low priority — flagging it as an optional follow-up rather than something that needs to change here.

(Posted on behalf of a review of this PR — overall it's a clean, well-scoped fix.)

Comment thread frontend/src/app/(auth)/login/page.tsx
Comment thread frontend/src/app/(auth)/login/page.tsx
@urzeye

urzeye commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@willem-bd Thanks for the review. I’ve marked the PR as a default behavior change and clarified that registration remains hidden while setup-status is unavailable, while existing users can still sign in.

Regarding the suggested page-level E2E coverage, I looked into adding fail → retry → recover scenarios for both /login and /setup. The existing Playwright setup has one relevant constraint: playwright.config.ts starts Next.js with DEER_FLOW_AUTH_DISABLED=1. As a result, the auth layout treats the test request as authenticated during SSR and redirects /login and /setup to /workspace before browser-side page.route() interception can exercise those pages.

I see two viable approaches:

  1. Extend the default Playwright config to start a second auth-enabled Next.js runtime for these specs. This keeps the tests in the default E2E command, but requires every E2E run to manage an additional server.
  2. Add a dedicated playwright.auth.config.ts and tests/e2e-auth/ suite, then run it as a separate step in the existing E2E workflow.

I’m leaning toward the second option because the repository already separates distinct test topologies through playwright.real-backend.config.ts and playwright.record.config.ts, and this would leave the default mock-based suite unchanged.

Would a dedicated auth E2E config and CI step be preferred here, or would you rather keep these specs in the default Playwright suite with a second runtime?

@github-actions github-actions Bot added area:ci GitHub Actions, CI config, repo tooling size/L PR changes 300-700 lines and removed size/M PR changes 100-300 lines labels Jul 23, 2026
@urzeye
urzeye requested a review from willem-bd July 23, 2026 07:18
@urzeye

urzeye commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@willem-bd Could you please re-review the latest changes when you have a chance? Thank you!

@WillemJiang
WillemJiang merged commit f881996 into bytedance:main Jul 26, 2026
12 checks passed
@WillemJiang WillemJiang added this to the 2.1.0 milestone Jul 26, 2026
jtaynl added a commit to jtaynl/deer-flow that referenced this pull request Jul 26, 2026
… resolved keep-ours-skin+graft-logic (bytedance#4371 setup-status phases/unavailable mode, useSettingsDialog refactor), migration-free (0008), chat() CHAT_OK, login/setup render WRI-branded
jtaynl added a commit to jtaynl/deer-flow that referenced this pull request Jul 26, 2026
The authoritative section still said 'Zero runtime hotfixes are currently
carrying', listing only two long-absorbed patches. That is the doc a future sync
consults, and it was actively misleading: we carry ~51 files of deployment config
and WRI re-skin, including surfaces that have already conflicted twice (07-19,
07-26).

Replaced with the real inventory, split into deployment/infrastructure (redis-strip,
readabilipy+Playwright, .dockerignore, deploy.sh, the schema_sync sentinel, and the
lead-agent <language> block) and the WRI re-skin (auth pages carrying grafted bytedance#4371
logic, the 49-string i18n rebrand, nav de-branding, landing page, 20 assets).

Also records what must NOT be changed (officialWebsite/githubTooltip/visitGithub;
the About page's deliberate DeerFlow attribution), notes that .env's UV_EXTRAS and
config.yaml are gitignored so they never appear in the diff, and adds a concrete
post-sync verification: 3 DeerFlow refs per locale, /login + /setup 200 and
WRI-branded.
yangjl pushed a commit to yangjl/deer-greenagent that referenced this pull request Jul 26, 2026
* fix(auth): recover from setup status timeouts

* test(auth): cover setup status recovery flows

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ci GitHub Actions, CI config, repo tooling area:frontend Next.js frontend under frontend/ risk:high High risk: backend API, agents, sandbox, auth, deps, CI size/L PR changes 300-700 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Setup/login page can spin on "Loading…" forever when Gateway is slow — add client-side timeout + retry UX

3 participants