From 8fcfa8bacb6995acc23243bdcf13f79321b4f373 Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Tue, 4 Aug 2026 19:59:48 +0000 Subject: [PATCH 1/3] Fix session loading spinner stalling with bounded retries --- .changeset/hungry-donkeys-repeat.md | 20 ++++++ packages/core/src/client/DefaultSpinner.tsx | 21 ++++-- .../core/src/client/require-session.spec.tsx | 64 +++++++++++++++++-- packages/core/src/client/require-session.tsx | 39 ++++++++++- packages/core/src/client/use-session.spec.tsx | 26 ++++++++ packages/core/src/client/use-session.ts | 50 +++++++++++++-- 6 files changed, 199 insertions(+), 21 deletions(-) create mode 100644 .changeset/hungry-donkeys-repeat.md diff --git a/.changeset/hungry-donkeys-repeat.md b/.changeset/hungry-donkeys-repeat.md new file mode 100644 index 0000000000..dcdeaeac24 --- /dev/null +++ b/.changeset/hungry-donkeys-repeat.md @@ -0,0 +1,20 @@ +--- +"@agent-native/core": patch +--- + +Stop stranding users on the loading spinner when the session endpoint is +unreadable. `useSession` retried a failed `/_agent-native/auth/session` every +second forever while holding `isLoading` true, so a transient 5xx, network +failure, or timeout produced a spinner that never resolved and carried no error +anywhere. It now retries a bounded number of times with backoff and then reports +a distinct `status: "unavailable"` alongside the existing `session`/`isLoading` +fields. + +`RequireSession` keys off that status: unreadable is no longer collapsed into +signed-out (which would bounce a signed-in user to the sign-in page over a blip) +nor into loading (which stranded them). It renders a notice with Try again and +Reload actions instead. + +The `DefaultSpinner` stall hint is also environment-aware now. It previously +told every visitor — including on hosted deployments — to "check the terminal +running the dev server", which is meaningless outside local development. diff --git a/packages/core/src/client/DefaultSpinner.tsx b/packages/core/src/client/DefaultSpinner.tsx index 3d5d24d5b9..cecb201abb 100644 --- a/packages/core/src/client/DefaultSpinner.tsx +++ b/packages/core/src/client/DefaultSpinner.tsx @@ -10,6 +10,21 @@ * is indistinguishable from a blank screen, and reads as "the app is broken" * rather than "look at the terminal" — that mis-read is what this text buys. */ + +/** + * Production wording wins whenever the build mode is unreadable: core is often + * consumed as prebuilt dist, where the Vite env is absent. A hosted visitor has + * no dev-server terminal, so pointing them at one is worse than saying less. + */ +function stallHint(): string { + const env = import.meta.env as Record | undefined; + const isDev = env?.DEV === true || env?.MODE === "development"; + if (isDev) { + return "Still loading. A first run compiles dependencies and can take a minute — if it does not finish, check the terminal running the dev server for errors."; + } + return "Still loading. This is taking longer than usual — try reloading the page, and let us know if it keeps happening."; +} + export function DefaultSpinner() { return (
-

- Still loading. A first run compiles dependencies and can take a minute — - if it does not finish, check the terminal running the dev server for - errors. -

+

{stallHint()}