@clerk/nextjs: onBeforeSetActive never settles when invalidateCacheAction rejects (e.g. after a redeploy), so setActive and signOut hang forever
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- authentication, frontend
Línea de trabajo
Comienza en dist/esm/app-router/client/ClerkProvider.js, en window.__internal_onBeforeSetActive, e inspecciona cómo invalidateCacheAction() gestiona un rechazo. Reprodúcelo con los pasos proporcionados para volver a desplegar con una pestaña obsoleta y, a continuación, verifica que el hook finaliza y que el inicio de sesión, el cierre de sesión y la reverificación se completan después de que falle la acción de invalidación de caché.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Preliminary Checks
- I have reviewed the documentation: https://clerk.com/docs
- I have searched for existing issues: https://github.com/clerk/javascript/issues
- I have not already reached out to Clerk support via email or Discord
- This issue is not a question, general help request, or anything other than a bug report directly related to Clerk.
Reproduction
No public repo: the steps below reproduce it in any App Router app using @clerk/nextjs, and the faulty code path is two lines, quoted below.
Publishable key
pk_test_YnJpZWYtc2N1bHBpbi00NS5jbGVyay5hY2NvdW50cy5kZXYk (a development instance; the bug does not depend on the instance, and we hit it in production first)
Description
The App Router client ClerkProvider sets (@clerk/nextjs 7.4.1, dist/esm/app-router/client/ClerkProvider.js; the same code is in 7.9.7):
window.__internal_onBeforeSetActive = (intent) => {
return new Promise((resolve) => {
const nextVersion = window?.next?.version || "";
if ((nextVersion.startsWith("15") || nextVersion.startsWith("16")) && intent === "sign-out") {
resolve();
} else {
void invalidateCacheAction().then(() => resolve());
}
});
};
If invalidateCacheAction() rejects, resolve is never called and the promise never settles. clerk-js awaits this hook inside setActive and signOut, so they hang forever.
The rejection is routine on any self-hosted Next 15/16 app. Server action IDs are salted with a per-build encryption key, so after every redeploy a tab loaded from the previous build calls an action ID the new server does not know. The server answers 404 with x-nextjs-action-not-found: 1 and logs Failed to find Server Action "…". This request might be from an older or newer deployment., and Next rejects the call with UnrecognizedActionError. A network failure has the same effect.
What we measured, in tabs opened before a deploy:
- Sign-in and reverification (a password change in
<UserProfile />) spin forever. signOut()calls the hook with no intent, so the Next 15/16"sign-out"fast path does not apply, and it awaits the hook beforeremoveSessions(). A stale-tab sign-out therefore leaves the user signed in.
Steps to reproduce:
- A fresh
create-next-app(App Router) with@clerk/nextjsand a<UserButton />on a page. NEXT_SERVER_ACTIONS_ENCRYPTION_KEY=$(openssl rand -base64 32) next build && next start, open the page and sign in.- Stop the server and rebuild with a different
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY(two plain local builds reuse the key cached in.next/cache/.rscinfoand keep the same IDs), thennext startagain. Do not reload the tab. - In that tab, sign out from the
<UserButton />, or runawait window.__internal_onBeforeSetActive()in the console.
Expected behavior:
The hook settles even when the cache-invalidation action fails (__internal_onAfterSetActive already calls router.refresh()), and sign-out, sign-in and reverification complete.
Actual behavior:
The promise never settles, the UI spins, and on sign-out the session is not removed. The console shows Uncaught (in promise) UnrecognizedActionError: Server Action "…" was not found on the server.
Suggested fix: invalidateCacheAction().then(() => resolve(), () => resolve()), or skip the action on Next ≥ 15 as #7873 proposed. Related prior art: #5084 and #7873 (closed unmerged), and #8122 (a never-settling variant with cacheComponents).
Our app-side workaround re-points window.__internal_onBeforeSetActive, from a descendant useEffect, to a wrapper that races Clerk's promise against an unhandledrejection listener for UnrecognizedActionError and a timeout.
Environment
next: 16.2.6 (webpack build, output: standalone, self-hosted)
@clerk/nextjs: 7.4.1 (the hook is identical in 7.9.7)
@clerk/clerk-js: 6.x (loaded from the CDN by major version)
react / react-dom: 19.2.4
node: 22 (production image)
browser: Chrome
- Lenguaje dominante
- TypeScript
- Estrellas
- 1.8k
- Forks
- 477
- Merge medio
- 1 d 18 h
- PR fusionados (30 d)
- 287
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de clerk/javascript
-
signIn.sso() ignores oidcPrompt for OAuth strategiesPosiblemente ocupada @wobsoriano la tomó hace 1 día. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
clerk/javascript#10119 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
clerk/javascript#10026 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 1-2 días Aptitud para principiantes 45/100
clerk/javascript#10118 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
clerk/javascript#10117 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 65/100
clerk/javascript#10011 ·
Los mantenedores suelen responder en 1 día
Todos los issues de clerk/javascript
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 84/100
answerLoops/answerLoops#345 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
siyuan-note/siyuan#20313 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
LanternOps/breeze#8254 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 82/100
gofish-graphics/gofish-graphics#1084 ·
Los mantenedores suelen responder en 1 día