It never reads authLoading, so on any cold load of /admin — typed URL, hard refresh, bookmark, browser reload — isAdmin is still false while the Firebase custom claims resolve, and the effect fires immediately and navigates away. The admin never sees the page.
Every other guarded route in the app gets this right, e.g. app/nodes/page.tsx:19 and app/systems/page.tsx:1188:
and app/settings/layout.tsx:30 (if (!loading && !canAccess) ...).
Observed in prod (git_sha 861ea41, 2026-08-23): a direct navigation to /admin bounces every time; reaching Admin only works by clicking the account-menu link from an already-mounted page, where the claims are already resolved. It compounds with the missing /dashboard route (separate issue), which is why the symptom looks like "/admin is a 404".
Fix: if (!authLoading && !isAdmin) router.replace(...), and gate the return null on authLoading too so it renders a loading state rather than nothing.
`app/admin/page.tsx:1064-1073`:
```ts
const { user, isAdmin } = useAuth();
useEffect(() => {
if (!isAdmin) router.replace("/dashboard");
}, [isAdmin, router]);
if (!isAdmin) return null;
```
It never reads `authLoading`, so on any cold load of `/admin` — typed URL, hard refresh, bookmark, browser reload — `isAdmin` is still `false` while the Firebase custom claims resolve, and the effect fires immediately and navigates away. The admin never sees the page.
Every other guarded route in the app gets this right, e.g. `app/nodes/page.tsx:19` and `app/systems/page.tsx:1188`:
```ts
if (!authLoading && !isAdmin && !isOperator) router.replace("/dashboard");
```
and `app/settings/layout.tsx:30` (`if (!loading && !canAccess) ...`).
Observed in prod (git_sha 861ea41, 2026-08-23): a direct navigation to `/admin` bounces every time; reaching Admin only works by clicking the account-menu link from an already-mounted page, where the claims are already resolved. It compounds with the missing `/dashboard` route (separate issue), which is why the symptom looks like "/admin is a 404".
Fix: `if (!authLoading && !isAdmin) router.replace(...)`, and gate the `return null` on `authLoading` too so it renders a loading state rather than nothing.
Verified against the deployed tree this morning (live /health SHA a1bdccf):
Commit be79499 (2026-08-23) is a confirmed ancestor of the live SHA.
drb-frontend/app/admin/page.tsx now gates the guard on authLoading before redirecting, and returns null rather than falling through while the token resolves.
A cold load — typed URL, hard refresh, bookmark — no longer bounces the admin off their own page while the ID token is still being fetched. The same shape is applied on /nodes, /systems and /settings. Closing.
Ref be79499. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.
(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)
**Fixed and live — closing as tracker drift.**
Verified against the deployed tree this morning (live `/health` SHA `a1bdccf`):
- Commit **`be79499`** (2026-08-23) is a confirmed ancestor of the live SHA.
- `drb-frontend/app/admin/page.tsx` now gates the guard on `authLoading` before redirecting, and returns `null` rather than falling through while the token resolves.
A cold load — typed URL, hard refresh, bookmark — no longer bounces the admin off their own page while the ID token is still being fetched. The same shape is applied on `/nodes`, `/systems` and `/settings`. Closing.
Ref `be79499`. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.
*(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)*
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
app/admin/page.tsx:1064-1073:It never reads
authLoading, so on any cold load of/admin— typed URL, hard refresh, bookmark, browser reload —isAdminis stillfalsewhile the Firebase custom claims resolve, and the effect fires immediately and navigates away. The admin never sees the page.Every other guarded route in the app gets this right, e.g.
app/nodes/page.tsx:19andapp/systems/page.tsx:1188:and
app/settings/layout.tsx:30(if (!loading && !canAccess) ...).Observed in prod (git_sha
861ea41, 2026-08-23): a direct navigation to/adminbounces every time; reaching Admin only works by clicking the account-menu link from an already-mounted page, where the claims are already resolved. It compounds with the missing/dashboardroute (separate issue), which is why the symptom looks like "/admin is a 404".Fix:
if (!authLoading && !isAdmin) router.replace(...), and gate thereturn nullonauthLoadingtoo so it renders a loading state rather than nothing.Fixed and live — closing as tracker drift.
Verified against the deployed tree this morning (live
/healthSHAa1bdccf):be79499(2026-08-23) is a confirmed ancestor of the live SHA.drb-frontend/app/admin/page.tsxnow gates the guard onauthLoadingbefore redirecting, and returnsnullrather than falling through while the token resolves.A cold load — typed URL, hard refresh, bookmark — no longer bounces the admin off their own page while the ID token is still being fetched. The same shape is applied on
/nodes,/systemsand/settings. Closing.Ref
be79499. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)