Skip to content

Bug: OAuth login fails on Windows — deep link not received by running instance #28

@ElioNeto

Description

@ElioNeto

Original issue tinyhumansai#2562 by @kr-du on 2026-05-24T08:02:09Z


Bug: OAuth login fails on Windows — deep link not received by running instance

Environment

  • OS: Windows 10 (Build 19045)
  • OpenHuman Version: v0.54.0 (2026-05-19)
  • Install Path: D:\OpenHuman\OpenHuman.exe

Description

When attempting to log in via GitHub OAuth, the browser callback completes successfully, but the openhuman:// deep link is never received by the running OpenHuman instance. The login flow hangs indefinitely with no feedback in the UI.

Steps to Reproduce

  1. Launch OpenHuman
  2. Click "Login with GitHub"
  3. Browser opens GitHub OAuth authorization page
  4. Authorize the application
  5. Browser redirects to https://api.tinyhumans.ai/auth/github/callback?code=...&state=...
  6. Server returns an HTML page titled "Opening OpenHuman" containing a deep link URL
  7. Browser shows a popup: "Open OpenHuman?" — click "Open"
  8. Nothing happens — OpenHuman UI remains unchanged

Investigation

Network is not the issue

The API server is reachable and responding correctly:

GET https://api.tinyhumans.ai/health → {"status":"ok"}

The OAuth callback page returns HTTP 200 with the deep link URL:

openhuman://#auth/github/error?error=Invalid%20or%20expired%20OAuth%20state

(The "Invalid state" error is a consequence of the deep link issue, not a separate problem — see below.)

Root cause: single-instance mutex kills secondary process without forwarding URL

When the browser triggers openhuman://..., Windows launches a new OpenHuman process via the registered protocol handler:

HKCU\Software\Classes\openhuman\shell\open\command
→ "D:\OpenHuman\OpenHuman.exe" "%1"

The new instance detects the existing instance via mutex and immediately exits:

15:44:43:INF:log [single-instance] pre-CEF mutex held by primary; secondary exiting (OPENHUMAN-TAURI-A fix)

The URL argument is NOT forwarded to the primary instance before exiting. The primary instance receives nothing — no deep link event, no auth callback, no log entry.

Evidence from logs

After triggering the deep link, the primary instance's logs show zero auth-related entries:

15:17:37:INF:jsonrpc [rpc] openhuman.auth_clear_session -> ok (3ms)
15:17:37:WRN:bus [auth] SessionExpired received — pausing background LLM work
... (normal polling continues, no login events) ...

Meanwhile, the secondary instance log shows it started and exited without forwarding:

15:44:43:INF:log [startup] platform: arch=x86_64 os=windows
15:44:43:INF:log [single-instance] pre-CEF mutex held by primary; secondary exiting (OPENHUMAN-TAURI-A fix)

Confirming the protocol handler is correctly registered

HKCU\Software\Classes\openhuman
  (default)    = URL:com.openhuman.app protocol
  URL Protocol = (empty)

HKCU\Software\Classes\openhuman\shell\open\command
  (default)    = "D:\OpenHuman\OpenHuman.exe" "%1"

Manual start "" "openhuman://test" triggers a new process, which also exits via the same mutex path without forwarding.

Expected Behavior

When a second instance is triggered via deep link / protocol handler, it should:

  1. Detect the existing instance via mutex
  2. Forward the URL to the primary instance via IPC (named pipe, TCP socket, or Tauri's deep-link plugin mechanism)
  3. Then exit

The primary instance should receive the deep link URL and process the OAuth callback.

Additional Context

  • The app's built-in update check also fails (error sending request for url (https://github.com/...)), suggesting the Tauri HTTP client (reqwest) does not respect system proxy settings or TUN virtual adapters. This is a separate issue but worth noting.
  • The auth_consume_login_token RPC method exists on the local server (port 7788), which suggests the intended flow is: deep link → extract token → call RPC. But the deep link never arrives, so the token is never extracted.

Possible Fix

In the single-instance check code, when the secondary instance detects the primary via mutex, it should pass the command-line arguments (specifically the deep link URL) to the primary instance before exiting. This is typically done via:

  • Named pipe IPC
  • TCP socket on a known localhost port
  • Windows COPYDATA message to the primary window handle

The Tauri tauri-plugin-deep-link should handle this, but it appears the forwarding mechanism is not working on Windows in this build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions