Skip to content

fix(*): recover from duplicate session cookies - #9286

Open
thiskevinwang wants to merge 7 commits into
mainfrom
kevin/aie-1066-javascript-fix-for-duplicate-__session-cookies-with-chips
Open

fix(*): recover from duplicate session cookies#9286
thiskevinwang wants to merge 7 commits into
mainfrom
kevin/aie-1066-javascript-fix-for-duplicate-__session-cookies-with-chips

Conversation

@thiskevinwang

@thiskevinwang thiskevinwang commented Jul 30, 2026

Copy link
Copy Markdown
Member

Description

Update Clerk-js to clean up cookies when /v1/environment loads (for CHIPS config), preventing duplicate partitioned & non-partitioned cookies.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c046539

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@clerk/clerk-js Patch
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview Jul 30, 2026 3:52pm
swingset Ready Ready Preview Jul 30, 2026 3:52pm

Request Review

@pkg-pr-new

pkg-pr-new Bot commented Jul 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9286

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9286

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9286

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9286

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9286

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9286

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9286

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9286

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9286

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9286

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9286

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9286

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9286

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9286

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9286

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9286

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9286

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9286

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9286

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9286

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9286

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9286

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9286

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9286

commit: c046539

Comment thread packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts Outdated
@thiskevinwang

Copy link
Copy Markdown
Member Author

!snapshot

@brkalow

brkalow commented Jul 30, 2026

Copy link
Copy Markdown
Member

!snapshot

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-07-30T15:54:46.947Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 0
🔴 Breaking changes 0
🟡 Non-breaking changes 0
🟢 Additions 0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on c046539.

@github-actions

Copy link
Copy Markdown
Contributor

Hey @brkalow - the snapshot version command generated the following package versions:

Package Version
@clerk/astro 4.0.5-snapshot.v20260730145336
@clerk/backend 3.14.1-snapshot.v20260730145336
@clerk/chrome-extension 3.1.64-snapshot.v20260730145336
@clerk/clerk-js 6.25.13-snapshot.v20260730145336
@clerk/electron 0.0.25-snapshot.v20260730145336
@clerk/electron-passkeys 0.0.4-snapshot.v20260730145336
@clerk/eslint-plugin 0.2.1-snapshot.v20260730145336
@clerk/expo 4.1.3-snapshot.v20260730145336
@clerk/expo-google-signin 1.0.1-snapshot.v20260730145336
@clerk/expo-passkeys 2.0.4-snapshot.v20260730145336
@clerk/express 2.1.49-snapshot.v20260730145336
@clerk/fastify 3.1.59-snapshot.v20260730145336
@clerk/headless 0.0.18-snapshot.v20260730145336
@clerk/hono 0.1.59-snapshot.v20260730145336
@clerk/localizations 4.13.10-snapshot.v20260730145336
@clerk/msw 0.0.54-snapshot.v20260730145336
@clerk/nextjs 7.6.4-snapshot.v20260730145336
@clerk/nuxt 3.0.1-snapshot.v20260730145336
@clerk/react 6.12.10-snapshot.v20260730145336
@clerk/react-router 3.6.3-snapshot.v20260730145336
@clerk/shared 4.25.10-snapshot.v20260730145336
@clerk/swingset 0.0.28-snapshot.v20260730145336
@clerk/tanstack-react-start 1.4.26-snapshot.v20260730145336
@clerk/testing 2.2.16-snapshot.v20260730145336
@clerk/ui 1.27.2-snapshot.v20260730145336
@clerk/upgrade 2.0.5-snapshot.v20260730145336
@clerk/vue 2.4.22-snapshot.v20260730145336

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/astro

npm i @clerk/astro@4.0.5-snapshot.v20260730145336 --save-exact

@clerk/backend

npm i @clerk/backend@3.14.1-snapshot.v20260730145336 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.1.64-snapshot.v20260730145336 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.25.13-snapshot.v20260730145336 --save-exact

@clerk/electron

npm i @clerk/electron@0.0.25-snapshot.v20260730145336 --save-exact

@clerk/electron-passkeys

npm i @clerk/electron-passkeys@0.0.4-snapshot.v20260730145336 --save-exact

@clerk/eslint-plugin

npm i @clerk/eslint-plugin@0.2.1-snapshot.v20260730145336 --save-exact

@clerk/expo

npm i @clerk/expo@4.1.3-snapshot.v20260730145336 --save-exact

@clerk/expo-google-signin

npm i @clerk/expo-google-signin@1.0.1-snapshot.v20260730145336 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@2.0.4-snapshot.v20260730145336 --save-exact

@clerk/express

npm i @clerk/express@2.1.49-snapshot.v20260730145336 --save-exact

@clerk/fastify

npm i @clerk/fastify@3.1.59-snapshot.v20260730145336 --save-exact

@clerk/headless

npm i @clerk/headless@0.0.18-snapshot.v20260730145336 --save-exact

@clerk/hono

npm i @clerk/hono@0.1.59-snapshot.v20260730145336 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.13.10-snapshot.v20260730145336 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.54-snapshot.v20260730145336 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.6.4-snapshot.v20260730145336 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@3.0.1-snapshot.v20260730145336 --save-exact

@clerk/react

npm i @clerk/react@6.12.10-snapshot.v20260730145336 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.6.3-snapshot.v20260730145336 --save-exact

@clerk/shared

npm i @clerk/shared@4.25.10-snapshot.v20260730145336 --save-exact

@clerk/swingset

npm i @clerk/swingset@0.0.28-snapshot.v20260730145336 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.4.26-snapshot.v20260730145336 --save-exact

@clerk/testing

npm i @clerk/testing@2.2.16-snapshot.v20260730145336 --save-exact

@clerk/ui

npm i @clerk/ui@1.27.2-snapshot.v20260730145336 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.5-snapshot.v20260730145336 --save-exact

@clerk/vue

npm i @clerk/vue@2.4.22-snapshot.v20260730145336 --save-exact

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a4dd75f-996b-4589-a500-205e32727c72

📥 Commits

Reviewing files that changed from the base of the PR and between dbf96f4 and c046539.

📒 Files selected for processing (1)
  • .changeset/duplicate-session-cookies.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/clerk-ios (auto-detected)
  • clerk/clerk-android (auto-detected)
  • clerk/cli (auto-detected)

📝 Walkthrough

Walkthrough

The change removes stale non-partitioned session and client UAT cookie variants before partitioned cookies are written or removed. Tests now validate cookie names, attributes, cleanup behavior, and operation ordering. AuthCookieService refreshes the session token and development cookies when partitioned-cookie support resolves during an environment update. The changeset now scopes the patch release to @clerk/clerk-js.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: fixing recovery from duplicate session cookies.
Description check ✅ Passed The description is directly related to the changeset and summarizes the cookie recovery fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/backend/src/tokens/clerkRequest.ts (1)

117-130: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Double-parsing makes get() and getAll() disagree on some values.

cookie.parse normalizes values (strips surrounding double quotes, skips invalid names), while parseCookiePairs returns raw slices. For a quoted cookie value, get(name) returns the unquoted value but getAll(name)[0] returns it with quotes, so session-token selection can operate on a different string than the legacy path. Since CookieMap.append already sets the first value for a name, a single pass over parseCookiePairs (or normalizing pair values the same way parse does) keeps both APIs consistent and avoids parsing the header twice.

♻️ Single-pass alternative
   private parseCookies(req: Request) {
     const cookieHeader = this.decodeCookieValue(req.headers.get('cookie') || '');
-    const cookiesRecord = parse(cookieHeader);
     const cookies = new CookieMap();
 
-    for (const [name, value] of Object.entries(cookiesRecord)) {
-      cookies.set(name, value);
-    }
-
     for (const [name, value] of this.parseCookiePairs(cookieHeader)) {
       cookies.append(name, value);
     }
 
     return cookies;
   }

Note this drops the parse import if no longer used elsewhere.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/backend/src/tokens/clerkRequest.ts` around lines 117 - 130, Update
the cookie construction logic around CookieMap and parseCookiePairs to use a
single parsing path, removing the separate cookie.parse/Object.entries pass.
Ensure pair values are normalized consistently with the existing parse behavior
so get() and getAll() return identical values, and remove the parse import if it
is no longer used.
packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts (1)

191-198: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Both new ordering tests assert absolute invocationCallOrder offsets. invocationCallOrder is a shared, process-wide counter, so unrelated mock calls interleaving between the removes and sets shift the expected numbers (visible already in the +4..+7 gaps in the clientUat test) and break the tests for reasons unrelated to ordering.

  • packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts#L191-L198: replace the four-element offset array with a relative check, e.g. expect(Math.max(...mockRemove.mock.invocationCallOrder)).toBeLessThan(Math.min(...mockSet.mock.invocationCallOrder)).
  • packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts#L222-L231: apply the same relative remove-before-set assertion instead of the +4/+5/+6/+7 and +8/+9 offsets.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts` around
lines 191 - 198, Replace the absolute invocationCallOrder offset assertions with
relative remove-before-set checks in the ordering tests. In
packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts lines 191-198
and packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts lines
222-231, assert that the latest mockRemove invocation occurs before the earliest
mockSet invocation, preserving the intended ordering without assuming contiguous
global call numbers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/backend/src/tokens/authenticateContext.ts`:
- Around line 383-406: Update selectBestSessionToken so candidates are filtered
by sessionTokenBelongsToInstance before applying sessionTokenUsable, ensuring a
fresh foreign-instance token cannot outrank this instance’s token. Preserve the
existing cross-instance fallback only when no instance-owned candidates exist,
and retain freshest-token selection within the chosen set.

In `@packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts`:
- Around line 173-188: Update the client fixture in the “clears non-partitioned
domain variants before writing partitioned cookies” test to satisfy the
ClientResource type, using an existing typed helper or an explicit cast for this
minimal shape. Keep the fixture’s runtime fields and test behavior unchanged.

---

Nitpick comments:
In `@packages/backend/src/tokens/clerkRequest.ts`:
- Around line 117-130: Update the cookie construction logic around CookieMap and
parseCookiePairs to use a single parsing path, removing the separate
cookie.parse/Object.entries pass. Ensure pair values are normalized consistently
with the existing parse behavior so get() and getAll() return identical values,
and remove the parse import if it is no longer used.

In `@packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts`:
- Around line 191-198: Replace the absolute invocationCallOrder offset
assertions with relative remove-before-set checks in the ordering tests. In
packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts lines 191-198
and packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts lines
222-231, assert that the latest mockRemove invocation occurs before the earliest
mockSet invocation, preserving the intended ordering without assuming contiguous
global call numbers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 877419f5-e8cb-4311-ba98-1f614df51932

📥 Commits

Reviewing files that changed from the base of the PR and between d32ea2a and dbf96f4.

📒 Files selected for processing (11)
  • .changeset/duplicate-session-cookies.md
  • packages/backend/src/tokens/__tests__/authenticateContext.test.ts
  • packages/backend/src/tokens/__tests__/clerkRequest.test.ts
  • packages/backend/src/tokens/authenticateContext.ts
  • packages/backend/src/tokens/clerkRequest.ts
  • packages/clerk-js/src/core/auth/AuthCookieService.ts
  • packages/clerk-js/src/core/auth/__tests__/AuthCookieService.test.ts
  • packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts
  • packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts
  • packages/clerk-js/src/core/auth/cookies/clientUat.ts
  • packages/clerk-js/src/core/auth/cookies/session.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go (manual)
  • clerk/dashboard (manual)
  • clerk/accounts (manual)
  • clerk/backoffice (manual)
  • clerk/clerk (manual)
  • clerk/clerk-docs (manual)
  • clerk/cloudflare-workers (manual)
  • clerk/clerk-ios (auto-detected)
  • clerk/clerk-android (auto-detected)
  • clerk/cli (auto-detected)

Comment on lines +383 to +406
private selectBestSessionToken(tokens: string[]) {
const fallbackToken = tokens[0];
const usableCandidates: Array<{ token: string; data: Jwt }> = [];

for (const token of tokens) {
const data = this.decodeSessionToken(token);

if (data && this.sessionTokenUsable(data)) {
usableCandidates.push({ token, data });
}
}

const candidatesForInstance = usableCandidates.filter(candidate =>
this.sessionTokenBelongsToInstance(candidate.data),
);
const candidates = candidatesForInstance.length ? candidatesForInstance : usableCandidates;
const freshestCandidate = candidates.reduce<(typeof candidates)[number] | undefined>(
(freshest, candidate) =>
!freshest || candidate.data.payload.iat > freshest.data.payload.iat ? candidate : freshest,
undefined,
);

return freshestCandidate?.token || fallbackToken;
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Usability filter runs before the instance filter, so a foreign-instance token can win over this instance's token.

usableCandidates is built first, then narrowed by instance. If this instance's duplicate is expired but a co-hosted app's duplicate (same eTLD+1, different iss) is fresh, candidatesForInstance is empty and the foreign token is selected as sessionTokenInCookie. Preferring instance ownership before usability keeps selection scoped to this instance and only falls back cross-instance when nothing matches.

♻️ Suggested ordering
-    const candidatesForInstance = usableCandidates.filter(candidate =>
-      this.sessionTokenBelongsToInstance(candidate.data),
-    );
-    const candidates = candidatesForInstance.length ? candidatesForInstance : usableCandidates;
+    const candidatesForInstance = usableCandidates.filter(candidate =>
+      this.sessionTokenBelongsToInstance(candidate.data),
+    );
+    const instanceTokens = tokens
+      .map(token => ({ token, data: this.decodeSessionToken(token) }))
+      .filter((c): c is { token: string; data: Jwt } => !!c.data && this.sessionTokenBelongsToInstance(c.data));
+    const candidates = candidatesForInstance.length
+      ? candidatesForInstance
+      : instanceTokens.length
+        ? instanceTokens
+        : usableCandidates;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private selectBestSessionToken(tokens: string[]) {
const fallbackToken = tokens[0];
const usableCandidates: Array<{ token: string; data: Jwt }> = [];
for (const token of tokens) {
const data = this.decodeSessionToken(token);
if (data && this.sessionTokenUsable(data)) {
usableCandidates.push({ token, data });
}
}
const candidatesForInstance = usableCandidates.filter(candidate =>
this.sessionTokenBelongsToInstance(candidate.data),
);
const candidates = candidatesForInstance.length ? candidatesForInstance : usableCandidates;
const freshestCandidate = candidates.reduce<(typeof candidates)[number] | undefined>(
(freshest, candidate) =>
!freshest || candidate.data.payload.iat > freshest.data.payload.iat ? candidate : freshest,
undefined,
);
return freshestCandidate?.token || fallbackToken;
}
private selectBestSessionToken(tokens: string[]) {
const fallbackToken = tokens[0];
const usableCandidates: Array<{ token: string; data: Jwt }> = [];
for (const token of tokens) {
const data = this.decodeSessionToken(token);
if (data && this.sessionTokenUsable(data)) {
usableCandidates.push({ token, data });
}
}
const candidatesForInstance = usableCandidates.filter(candidate =>
this.sessionTokenBelongsToInstance(candidate.data),
);
const instanceTokens = tokens
.map(token => ({ token, data: this.decodeSessionToken(token) }))
.filter(
(c): c is { token: string; data: Jwt } =>
!!c.data && this.sessionTokenBelongsToInstance(c.data),
);
const candidates = candidatesForInstance.length
? candidatesForInstance
: instanceTokens.length
? instanceTokens
: usableCandidates;
const freshestCandidate = candidates.reduce<(typeof candidates)[number] | undefined>(
(freshest, candidate) =>
!freshest || candidate.data.payload.iat > freshest.data.payload.iat ? candidate : freshest,
undefined,
);
return freshestCandidate?.token || fallbackToken;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/backend/src/tokens/authenticateContext.ts` around lines 383 - 406,
Update selectBestSessionToken so candidates are filtered by
sessionTokenBelongsToInstance before applying sessionTokenUsable, ensuring a
fresh foreign-instance token cannot outrank this instance’s token. Preserve the
existing cross-instance fallback only when no instance-owned candidates exist,
and retain freshest-token selection within the chosen set.

Comment on lines +173 to +188
it('clears non-partitioned domain variants before writing partitioned cookies', () => {
let usePartitionedCookies = false;
const cookieHandler = createClientUatCookie(mockCookieSuffix, {
usePartitionedCookies: () => usePartitionedCookies,
});
const client = {
id: 'test-client',
updatedAt: new Date('2024-01-01'),
signedInSessions: ['session1'],
};

cookieHandler.set(client);
usePartitionedCookies = true;
mockSet.mockClear();
mockRemove.mockClear();
cookieHandler.set(client);

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -i 'clientUat.test.ts' -t f --exec rg -nP -C2 'cookieHandler\.set\(|as any|as unknown as'

Repository: clerk/javascript

Length of output: 2065


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## tsconfig files\n'
fd -a 'tsconfig*.json' packages/clerk-js . | sed 's#^\./##' | sort

printf '\n## package.json test/typecheck scripts\n'
rg -n '"(test|typecheck|check|lint|tsc)"\s*:\s*' packages/clerk-js/package.json package.json -n

printf '\n## ClientResource and createClientUatCookie definitions\n'
rg -n 'type ClientResource|interface ClientResource|createClientUatCookie|set\(client' packages/clerk-js/src -g '!**/dist/**' -g '!**/build/**'

printf '\n## test file excerpt\n'
sed -n '1,260p' packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts

Repository: clerk/javascript

Length of output: 14517


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## relevant tsconfig contents\n'
for f in packages/clerk-js/tsconfig.json packages/clerk-js/tsconfig.*.json; do
  [ -f "$f" ] && { echo "--- $f"; cat "$f"; echo; }
done

printf '\n## source types around ClientResource\n'
sed -n '1,220p' $(rg -l 'ClientResource' packages/clerk-js/src | head -n 5)

printf '\n## test file lines 160-200\n'
sed -n '160,200p' packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts

Repository: clerk/javascript

Length of output: 11138


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '## package tsconfig references'
rg -n '"include"|"exclude"|__tests__|test' packages/clerk-js/tsconfig*.json packages/clerk-js/package.json

echo
echo '## ClientResource definition'
rg -n 'export (type|interface) ClientResource|type ClientResource|interface ClientResource' packages/clerk-js/src packages/clerk-js -g '!**/dist/**' -g '!**/build/**'

echo
echo '## createClientUatCookie signature'
rg -n 'function createClientUatCookie|const createClientUatCookie|createClientUatCookie\s*=' packages/clerk-js/src -g '!**/dist/**' -g '!**/build/**'

Repository: clerk/javascript

Length of output: 922


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '## ClientResource definition candidates\n'
rg -n --hidden --glob '!**/dist/**' --glob '!**/build/**' 'export (type|interface) ClientResource|type ClientResource =|interface ClientResource' packages/shared packages/clerk-js packages -g '!**/*.map' | head -n 50

printf '\n## ClientResource related re-exports\n'
rg -n --hidden --glob '!**/dist/**' --glob '!**/build/**' 'ClientResource' packages/shared packages/clerk-js/src | head -n 80

Repository: clerk/javascript

Length of output: 4730


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# locate the shared type definition and the exact shape used by ClientUatCookieHandler
files=$(rg -l --hidden --glob '!**/dist/**' --glob '!**/build/**' 'ClientResource' packages/shared packages/clerk-js/src | head -n 20)
printf '%s\n' "$files"

printf '\n## definition excerpts\n'
for f in $files; do
  echo "--- $f"
  sed -n '1,240p' "$f" | rg -n 'ClientResource|signedInSessions|updatedAt|id:' -n -C2 || true
done

Repository: clerk/javascript

Length of output: 10076


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '## files named around shared types\n'
fd -a 'types.ts' packages/shared packages/clerk-js/src | head -n 50
printf '\n## files with ClientResource in shared package\n'
rg -l --hidden --glob '!**/dist/**' --glob '!**/build/**' 'ClientResource' packages/shared | head -n 50

Repository: clerk/javascript

Length of output: 1448


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '## locate ClientResource definition'
rg -n --hidden --glob '!**/dist/**' --glob '!**/build/**' 'ClientResource' packages/shared packages/clerk-js/src | head -n 80

echo
echo '## package/shared type files'
fd -a 'types*.ts' packages/shared | head -n 50

Repository: clerk/javascript

Length of output: 5444


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the shared type declaration and inspect the minimal surrounding context.
type_file=$(rg -l --hidden --glob '!**/dist/**' --glob '!**/build/**' 'export (type|interface) ClientResource|type ClientResource =|interface ClientResource' packages/shared packages/clerk-js/src | head -n 1)
echo "## type file: $type_file"
[ -n "$type_file" ] && sed -n '1,260p' "$type_file"

echo
echo "## direct references in clientUat.ts"
sed -n '1,220p' packages/clerk-js/src/core/auth/cookies/clientUat.ts

Repository: clerk/javascript

Length of output: 7485


This fixture isn't a ClientResource. client only has id, updatedAt, and signedInSessions, so this test file will fail tsc unless you use a typed helper or an explicit cast for the minimal test shape.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts` around
lines 173 - 188, Update the client fixture in the “clears non-partitioned domain
variants before writing partitioned cookies” test to satisfy the ClientResource
type, using an existing typed helper or an explicit cast for this minimal shape.
Keep the fixture’s runtime fields and test behavior unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants