Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(electron,ui): Don't run passkey autofill as a modal prompt by jeremy-clerk · Pull Request #9500 · clerk/javascript · GitHub
Skip to content

fix(electron,ui): Don't run passkey autofill as a modal prompt - #9500

Merged
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional
Aug 19, 2026
Merged

fix(electron,ui): Don't run passkey autofill as a modal prompt#9500
jeremy-clerk merged 1 commit into
mainfrom
jw/fix-native-passkey-conditional

Conversation

@jeremy-clerk

Copy link
Copy Markdown
Contributor

Description

The Electron passkey provider reported autofill as supported but serviced the request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in form mounted, before user intent. On custom-scheme windows the same probe would fail with passkey_not_supported.

  • get() honors conditionalUI instead of hardcoding to false, so the renderer path performs conditional mediation. A conditional request that would resolve to the native or unsupported path is aborted and doesn't fall back to the native path.
  • isSupported() and isAutoFillSupported() go through the same routing rules as decidePath() & they stop advertising capabilities the resolved path cannot deliver.
  • SignInStart resolves both WebAuthn predicates against the Clerk instance before falling back to the shared helpers, so a host-provided passkey provider can influence whether the autofill flow starts at all.

Signing in with the “Use passkey” button/action is unchanged.

@clerk/electron alone does not fix the reported behaviour, the gate that starts the flow lives in @clerk/ui.

Fixes#9496

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:

The Electron passkey provider reported autofill as supported but serviced the
request as a modal ceremony, so an OS passkey sheet opened as soon as the sign-in
form mounted, before any user intent.
- `get()` now honours `conditionalUI` instead of hardcoding it to `false`, so the
renderer path performs real conditional mediation. When a conditional request
would resolve to the native or unsupported path it is quietly aborted rather
than prompting, and it no longer falls back to the native path on error.
- `isSupported()` and `isAutoFillSupported()` now answer through the same routing
rules as `decidePath()`, so they stop advertising capabilities the resolved path
cannot deliver.
- `SignInStart` resolves both WebAuthn predicates against the Clerk instance
before falling back to the shared helpers, so a host-provided passkey provider
can influence whether the autofill flow starts at all.
Closes#9496
@vercel

vercelBot commented Aug 19, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 19, 2026 4:44am
swingsetReadyReadyPreviewAug 19, 2026 4:44am

Request Review

@changeset-bot

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 70a6432

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

This PR includes changesets to release 4 packages
NameType
@clerk/electronPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch
@clerk/swingsetPatch

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

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 70a6432

@coderabbitai

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: 82aa3ae6-9c4a-44ee-b7d8-a0c507adb29d

📥 Commits

Reviewing files that changed from the base of the PR and between 72ffc81 and 70a6432.

📒 Files selected for processing (8)
  • .changeset/rude-pianos-smoke.md
  • packages/electron/README.md
  • packages/electron/src/passkeys/__tests__/index.test.ts
  • packages/electron/src/passkeys/__tests__/strategy.test.ts
  • packages/electron/src/passkeys/index.ts
  • packages/electron/src/passkeys/renderer/strategy.ts
  • packages/ui/src/components/SignIn/SignInStart.tsx
  • packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
🔗 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/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

Included review availability: 5 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

Electron passkey routing now supports conditional renderer requests and aborts conditional requests when only native routing is available. Renderer eligibility accounts for mode, origin, WebAuthn support, and legacy macOS Electron versions. Autofill support checks are asynchronous and require an eligible renderer path. Sign-in detection uses Clerk’s internal WebAuthn support APIs when available. Tests and documentation cover the updated behavior.

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

Merge Risk:⚪ Minimal · up to 70a64

The change updates passkey autofill routing so it waits for user intent while preserving explicit passkey sign-in behavior. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • clerk/javascript issue 9265 — Both changes update SignInStart passkey autofill handling and prevent unsupported autofill attempts.

Suggested reviewers:wobsoriano

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly identifies the Electron and UI fix that prevents passkey autofill from opening a modal prompt.
Description check✅ PassedThe description accurately explains the modal autofill bug, routing changes, capability checks, UI changes, and preserved explicit sign-in behavior.
Linked Issues check✅ PassedThe changes address issue #9496 by enabling conditional mediation, preventing invalid fallbacks, aligning capability checks, and preserving explicit passkey sign-in.
Out of Scope Changes check✅ PassedThe changes remain within scope and include related implementation, tests, documentation, and release metadata for the passkey autofill fix.

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

@github-actions

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-19T04:49:30.290Z

Summary

MetricCount
Packages analyzed19
Packages with changes0
🔴 Breaking changes0
🟡 Non-breaking changes0
🟢 Additions0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 70a6432.

@jeremy-clerk
jeremy-clerk merged commit a52d486 into mainAug 19, 2026
84 of 85 checks passed
@jeremy-clerk
jeremy-clerk deleted the jw/fix-native-passkey-conditional branch August 19, 2026 05:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[@clerk/electron] Passkey autofill runs as a modal prompt: OS passkey dialog opens as soon as sign-in mounts

2 participants

@jeremy-clerk@wobsoriano