Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ahnafnafee/2fadd71e4f2734fdabdd468047486717 to your computer and use it in GitHub Desktop.

Select an option

Save ahnafnafee/2fadd71e4f2734fdabdd468047486717 to your computer and use it in GitHub Desktop.
Continue with Google opens nothing on Windows -- root cause: Windows Subsystem for Android (WSA) hijacking google.com links via App URI Handlers. Full diagnosis + fix + reusable playbook.

"Continue with Google" opens nothing on Windows — and it's not the browser, the app, or your account

TL;DR: A desktop app's "Sign in with Google" button silently did nothing — the browser never opened. After a long hunt it turned out Windows Subsystem for Android (WSA) had registered Google's sign-in domains (accounts.google.com, etc.) as "App URI Handlers" ("Apps for websites"), so Windows routed every shell-opened google.com link to a crashing Android app instead of the browser. It affected every browser and every app that opens Google login via the OS. Fix: remove the hijacking association (uninstall/repair WSA, or disable App URI Handlers) and reboot.

This write-up documents the symptom, the full diagnostic journey (including the wrong turns, because they're instructive), the root cause, the fix, and a reusable playbook so you can diagnose "a URL opens the wrong app / nothing" in minutes next time.


Symptoms

  • Clicking "Continue with Google" in an Electron-based IDE (Google Antigravity, a VS Code fork) showed a brief busy cursor, then nothing — no browser, no error.
  • The app's logs proved it was working: it built the Google OAuth URL and started its localhost loopback callback server, then waited forever for a callback that never came:
    [Auth] Localhost server listening on port 61811
    [Auth] Login URL: https://accounts.google.com/o/oauth2/v2/auth?...&redirect_uri=http://localhost:61811/oauth-callback
    
  • Reproduced outside the app with the Windows shell:
    Start-Process "https://accounts.google.com/"   # ❌ nothing opens
    Start-Process "https://example.com/"            # ✅ opens fine
    cmd /c start "" "https://www.google.com/"        # ❌ nothing
  • But these worked:
    • Typing accounts.google.com in the browser's address bar (internal navigation).
    • Launching the browser executable directly with the URL:
      & "C:\Program Files\Google\Chrome\Application\chrome.exe" "https://accounts.google.com/"  #
    • The same Start-Process on a different machine (a laptop) — worked.

The decisive shape of the bug:

google.com URLs fail only when opened through the Windows shell (ShellExecute), in any browser, while example.com works and direct browser launches of google.com work.

That combination means it's not the browser, not the app, and not your Google account — it's Windows URL routing, scoped to a specific domain.


Root cause

Windows has a feature called App URI Handlers (Settings calls it "Apps for websites", a.k.a. web-to-app linking / deep links). A packaged app (MSIX/UWP) can declare in its manifest that it handles certain web hosts (e.g. https://accounts.google.com/*). Once Windows verifies the claim, ShellExecute of a matching URL is routed to the app instead of the browser.

Windows Subsystem for Android (WSA) bridges Android apps' intent-filter deep links into this system. This machine ran a sideloaded WSA "MindTheGapps" build (WSA with Google apps). Those Google Android apps declared intent filters for Google hosts, so WSA registered them as App URI Handlers. The Windows StateRepository ended up with:

accounts.google.com          → AppXrj7aa2qf075g758cpe0ja2w4p9   (a WSA-bridged Android app)
accounts.sandbox.google.com  → AppX98qyanmdz6zh0e44e6p0e...
assistant.google.com, bard.google.com, business.google.com, ... → various AppX...

So every shell-opened google.com link was handed to WsaClient.exe, which crashed (caught by Windows Error Reporting + the AV's crash handler) — producing exactly "nothing happens."

This is why it was browser-independent, survived Firefox Troubleshoot Mode and fresh profiles, didn't reproduce on a machine without WSA, and only worked via direct .exe launches (which bypass the shell's App-URI-Handler resolution).


How to diagnose it (reusable playbook)

Work from "what's the smallest reproduction" outward. Each step rules in/out a layer.

Step 0 — Characterize the failure precisely

Open the failing URL three ways and compare to a control (example.com):

# A) via the Windows shell (what apps use under the hood):
Start-Process "https://accounts.google.com/"
# B) control via the shell:
Start-Process "https://example.com/"
# C) directly via the browser executable (bypasses shell routing):
& "C:\Program Files\Google\Chrome\Application\chrome.exe" "https://accounts.google.com/"
Result pattern Points to
A fails, B works, C works Shell URL routing for that domain (this case)
A & C both fail The browser, an extension, or content/network block
A & B both fail Default-browser handler is broken (re-register it)
Everything works Background window / focus-stealing — the tab opened where you didn't look

Tip: launching a browser .exe directly with the URL is the key control — it skips ShellExecute/App-URI-Handler resolution, so if that works but Start-Process <url> doesn't, the problem is in the shell routing, not the browser.

Step 1 — Rule out the obvious shell/registry interception points

# Default browser for http/https
foreach ($p in 'https','http') {
  (Get-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\$p\UserChoice").ProgId
}
# IE security zones (a domain in "Restricted Sites" = zone 4 can block launching)
Get-ChildItem "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains" -Recurse
# Global ShellExecute hooks / injected DLLs
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks"
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows" | Select AppInit_DLLs,LoadAppInit_DLLs
# Browser block policies
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Google\Chrome\URLBlocklist" -EA SilentlyContinue
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\WebsiteFilter\Block" -EA SilentlyContinue
# hosts file
Select-String 'google' "$env:windir\System32\drivers\etc\hosts"

In this case all clean — which is the clue that it's the App-URI-Handler layer, not classic interception.

Step 2 — Watch the launch live: which process actually starts?

The single most decisive step. See whether the shell launches your browser, something else, or nothing.

Admin (reliable, ETW-backed):

Get-EventSubscriber | Unregister-Event -EA SilentlyContinue
$log=[System.Collections.ArrayList]::Synchronized([System.Collections.ArrayList]::new())
$cb={ $n=$Event.SourceEventArgs.NewEvent; [void]$Event.MessageData.Add("$($n.ProcessName) ppid=$($n.ParentProcessID)") }
Register-CimIndicationEvent -ClassName Win32_ProcessStartTrace -Action $cb -MessageData $log -SourceIdentifier s
Start-Sleep 1; Start-Process "https://www.google.com/?TEST"; Start-Sleep 3
Unregister-Event s; $log

Non-admin (fast Get-Process poller, grabs command lines):

$seen=@{}; Get-Process | %{ $seen[$_.Id]=$true }
Start-Process "https://www.google.com/?TEST"
$end=(Get-Date).AddSeconds(4)
while((Get-Date) -lt $end){
  foreach($p in Get-Process){ if(-not $seen[$p.Id]){ $seen[$p.Id]=$true
    $cl=(Get-CimInstance Win32_Process -Filter "ProcessId=$($p.Id)").CommandLine
    "$($p.ProcessName)  ::  $cl" }}
}

What it revealed here: for example.com the handoff was chrome.exe --single-argument https://example.com/... (browser launched ✅). For google.com it was WsaClient.exe (Windows Subsystem for Android) followed by WSACrashUploader.exe / WerFault.exe — i.e. the URL was routed to a crashing Android app, not the browser. That's the smoking gun.

Step 3 — Confirm the App URI Handler association

The associations live in the (locked) StateRepository SQLite DB. Copy it and pull ASCII strings around the host:

$srd = 'C:\ProgramData\Microsoft\Windows\AppRepository\StateRepository-Machine.srd'
$tmp = "$env:TEMP\sr.srd"; Copy-Item $srd $tmp -Force
$enc = [Text.Encoding]::GetEncoding(28591)
$txt = $enc.GetString([IO.File]::ReadAllBytes($tmp))
[regex]::Matches($txt,'[\x20-\x7E]{0,15}google\.com[\x20-\x7E]{0,40}') | %{$_.Value} | Sort-Object -Unique

Output like accounts.google.com → AppXrj7… confirms a packaged app claimed the host. The GUI equivalent: Settings → Apps → Advanced app settings → Apps for websites lists each app and the hosts it handles.

You can also list any installed WSA / suspicious packages:

Get-AppxPackage | ? { $_.Name -match 'WindowsSubsystemForAndroid|Wsa|Android' } | Select PackageFullName

The fix

Pick one (all reversible):

A. Remove the hijacking app (most targeted). If it's WSA you don't need:

Get-Process WsaClient,WsaService -EA SilentlyContinue | Stop-Process -Force
Get-AppxPackage *WindowsSubsystemForAndroid* | Remove-AppxPackage

If you do use WSA, instead uninstall the specific Android app that claimed the host, or reset WSA.

B. Disable web-to-app linking globally (keeps the app installed). All http(s) links then always open in the browser, never an app:

New-Item 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System' -Force | Out-Null
New-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System' `
  -Name EnableAppUriHandlers -PropertyType DWord -Value 0 -Force
# revert later: Remove-ItemProperty ... -Name EnableAppUriHandlers

C. GUI: Settings → Apps → Advanced app settings → Apps for websites → toggle the offending app Off.

⚠️ Reboot (or sign out) afterward. Windows caches URL→app routing per logon session — an Explorer restart is not enough. The policy and the deregistration only fully take effect after a reboot.

Verify:

Start-Process "https://www.google.com/"   # now opens in your default browser

Why it took so long (lessons / red herrings)

Honest list of wrong turns — each is a trap worth knowing:

  1. "Busy cursor then nothing" looks like a broken default-browser association. It wasn't — the association was fine; the URL was being routed away from it.
  2. A third-party account-manager tool (a local proxy/account-switcher for the IDE, built for an older app version) had also signed the user out and written tokens to the old install path after a version upgrade. Real, but a separate issue — it explained "logged out," not "browser won't open." Don't let a plausible-but-secondary finding stop the hunt.
  3. A runaway auth-retry loop in the IDE (loopback server restarting every ~150 ms) looked like the cause; it was a downstream symptom of being signed out, cleared by resetting the IDE's state — but the browser still didn't open.
  4. Firefox rabbit hole. With Firefox as default we blamed: a corrupt URL association (the empty ddeexec key — actually normal), &/%20/length in the URL (all fine), 60 extensions, Multi-Account Containers, even Mozilla's new built-in "Data Leak Blocker" (Firefox 144, which does ship a credential-domain blocklist incl. google.com — a great false positive, but it only blocks extension-initiated loads, and Troubleshoot Mode didn't fix the symptom).
  5. Process-count deltas are unreliable for catching a browser's transient command-line hand-off — use ETW Win32_ProcessStartTrace (admin) or a tight Get-Process poll, and confirm with the user's eyes.
  6. The breakthrough was switching the default browser to Chrome and finding it still failed for google.com — proving it was below the browser, in the Windows shell. The process watcher then caught WsaClient.exe.

The generalizable principle: when one specific domain's links open the wrong thing (or nothing) only via the shell, suspect App URI Handlers / "Apps for websites." Any MSIX/UWP/WSA app can claim a host and silently intercept it system-wide.


One-glance flowchart

"Continue with Google" / a link does nothing
        │
        ▼
Start-Process <url>  vs  Start-Process <control-url>  vs  browser.exe <url> directly
        │
   only <url> via shell fails, browser.exe <url> works
        │
        ▼
Watch the launch (Win32_ProcessStartTrace / Get-Process poll)
        │
   a NON-browser process launches (e.g. WsaClient.exe) ──► App URI Handler hijack
        │
        ▼
Confirm: StateRepository / Settings ▸ Apps ▸ Apps for websites  →  <host> → AppX…
        │
        ▼
Fix: remove app / EnableAppUriHandlers=0 / toggle off  →  REBOOT  →  verify

Environment: Windows 11, Google Antigravity (VS Code fork, Electron), Windows Subsystem for Android 2311.40000.5.0 (MindTheGapps). The OAuth flow uses a localhost loopback redirect, so the browser used for sign-in is irrelevant — only the redirect back to http://localhost:<port> matters.

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