Symptom
After a Clerk SDK major upgrade (v5 → v7 in our case), /setup-browser-cookies imports fresh cookies but the browse session still enters an infinite redirect loop: Refreshing the session token resulted in an infinite redirect loop. Recovery requires clearing the browse session's localStorage manually.
Root cause
Clerk stores a clerk_environment entry in localStorage that includes the SDK major version (clerk_js_version: "5") and an exp timestamp. After upgrading to v7 server-side, the browse browser's localStorage still has the v5-shaped entry with an expired exp. Clerk's client JS reads the stale entry first and fails to reconcile with the fresh v7 server state.
cookie-import-browser touches cookies only — localStorage survives. Every re-import hits the same stale state.
Reference: clerk/javascript#1436 — same failure mode, same fix (clear local/session storage).
Proposed change
In cookie-import-browser, before applying imported cookies to a given origin, also clear its localStorage and sessionStorage:
```ts
// Pseudocode — wherever cookies are applied per origin
await page.goto(origin);
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});
await context.addCookies(importedCookiesForOrigin);
```
Behind an opt-out flag if there's concern about breaking flows that depend on pre-existing localStorage:
```
cookie-import-browser [browser] [--domain ] [--keep-storage]
```
Default should be "clear" — the stated purpose of the command is to bring the browse session into the same authenticated state as the real browser, and for any modern auth SDK (Clerk, Auth0, Firebase, Supabase) that state lives across cookies and localStorage.
Risk
Low. Anyone currently relying on pre-existing localStorage in the browse session is doing so implicitly — there's no documented contract that cookie-import-browser preserves it. The --keep-storage escape hatch covers the edge case.
Acceptance
Running cookie-import-browser against a site that stores auth metadata in localStorage (Clerk, Auth0, etc.) leaves the browse session in a consistent state with the real browser, with no stale version entries.
Context
Origin: B81 / SIX-132 in our internal tracker. Keel-side workaround lives in a wrapper skill (/auth-reset) + shell script that navigates to the origin and clears storage via browse js. Would love to retire that once this lands upstream.
Symptom
After a Clerk SDK major upgrade (v5 → v7 in our case),
/setup-browser-cookiesimports fresh cookies but the browse session still enters an infinite redirect loop:Refreshing the session token resulted in an infinite redirect loop. Recovery requires clearing the browse session's localStorage manually.Root cause
Clerk stores a
clerk_environmententry in localStorage that includes the SDK major version (clerk_js_version: "5") and anexptimestamp. After upgrading to v7 server-side, the browse browser's localStorage still has the v5-shaped entry with an expiredexp. Clerk's client JS reads the stale entry first and fails to reconcile with the fresh v7 server state.cookie-import-browsertouches cookies only — localStorage survives. Every re-import hits the same stale state.Reference: clerk/javascript#1436 — same failure mode, same fix (clear local/session storage).
Proposed change
In
cookie-import-browser, before applying imported cookies to a given origin, also clear its localStorage and sessionStorage:```ts
// Pseudocode — wherever cookies are applied per origin
await page.goto(origin);
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});
await context.addCookies(importedCookiesForOrigin);
```
Behind an opt-out flag if there's concern about breaking flows that depend on pre-existing localStorage:
```
cookie-import-browser [browser] [--domain ] [--keep-storage]
```
Default should be "clear" — the stated purpose of the command is to bring the browse session into the same authenticated state as the real browser, and for any modern auth SDK (Clerk, Auth0, Firebase, Supabase) that state lives across cookies and localStorage.
Risk
Low. Anyone currently relying on pre-existing localStorage in the browse session is doing so implicitly — there's no documented contract that
cookie-import-browserpreserves it. The--keep-storageescape hatch covers the edge case.Acceptance
Running
cookie-import-browseragainst a site that stores auth metadata in localStorage (Clerk, Auth0, etc.) leaves the browse session in a consistent state with the real browser, with no stale version entries.Context
Origin: B81 / SIX-132 in our internal tracker. Keel-side workaround lives in a wrapper skill (
/auth-reset) + shell script that navigates to the origin and clears storage viabrowse js. Would love to retire that once this lands upstream.