Skip to content

Windows: auth login fails with "redirect uri is malformed or doesn't match" — cmd /c start truncates the auth URL at the first & #46

Description

@PJH1993

Summary

On Windows, apollo auth login (v2.0.0, apollo-windows-x64.exe) always fails: the browser opens Apollo's authorize page showing

The requested redirect uri is malformed or doesn't match client redirect URI.

Nothing is wrong with the registered client — the URL the browser receives is truncated.

Root cause

openBrowser in src/oauth.ts launches the browser on win32 via:

spawnSync('cmd', ['/c', 'start', '', url])

Node only quotes arguments containing whitespace, so the auth URL is passed to cmd.exe unquoted — and cmd treats every unquoted & in the query string as a command separator. The browser therefore receives only:

https://mcp.apollo.io/mcp/oauth_metadata/redirect_to_authorize?client_id=<id>

i.e. everything from &redirect_uri=... onward is cut off (the remaining query params are executed as no-op cmd commands). With no redirect_uri in the request, the server correctly rejects it with the misleading "malformed or doesn't match" error.

Because cmd itself exits 0, result.status !== 0 never triggers, so the "Could not open browser automatically. Visit: ..." fallback with the full URL is never shown — the user has no way to recover.

Reproduction

Windows 11, apollo-windows-x64.exe v2.0.0 from the GitHub release:

apollo auth login

Browser opens → Apollo error page as above, 100% reproducible. Verified the truncation independently: registering a client via POST /api/v1/oauth/applications/register_oauth_client with redirect_uris: ["http://localhost:3421/callback"] succeeds, and visiting the full authorize URL manually works fine (login completes, token saved).

Workaround (for other Windows users)

Force the browser-open to fail so the CLI prints the full URL, then open it manually:

$env:PATH = ""; & "$env:LOCALAPPDATA\Programs\apollo-cli\apollo.exe" auth login
# copy the printed URL, then in another terminal:
Start-Process "<printed url>"

Suggested fix

Avoid cmd's metacharacter parsing entirely, e.g.:

process.platform === 'win32'
  ? spawnSync('rundll32', ['url.dll,FileProtocolHandler', url])

(no shell involved, handles & fine), or keep cmd /c start but escape the URL (url.replace(/[&^|<>]/g, '^$&')), or shell out to PowerShell's Start-Process. Also worth printing the URL unconditionally (many CLIs do) so a failed auto-open is always recoverable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions