Where does the bug appear (feature/product)?
Cursor SDK
Describe the Bug
AsyncClient.launch_bridge / Client.launch_bridge intermittently fails (~1.5% of launches) with:
Error: Bridge exited before discovery with status 1: cursor-sdk-bridge failed: Error: Missing value for --tool-callback-auth-token
at takeValue (…/cursor_sdk/_vendor/bridge/dist/bin/cursor-sdk-bridge.js:155:15)
at parseArgs (…:125:48)
at main (…:24:18)
It’s non-deterministic and depends only on a randomly generated token, so the same code “randomly crashes Python” with no caller-side cause.
Root cause
Two vendored components disagree on the - prefix:
The SDK mints callback bearer tokens with secrets.token_urlsafe(32) in both cursor_sdk/_tool_callback.py and cursor_sdk/_store_callback.py:
def new_auth_token() → str:
return secrets.token_urlsafe(32)
token_urlsafe uses the base64url alphabet [A-Za-z0-9-], so a token can begin with -.
The token is passed positionally on the bridge CLI (_tool_callback.tool_callback_bridge_argv):
return [“–tool-callback-url”, endpoint.url,
“–tool-callback-auth-token”, endpoint.auth_token]
The bundled bridge’s takeValue treats any value starting with - as a missing flag value (cursor-sdk-bridge.js):
function takeValue(args, index, flag) {
const value = args[index];
if (value === undefined || value.startsWith(“-”)) {
throw new Error(Missing value for ${flag});
}
return value;
}
So whenever a generated token starts with -, the bridge aborts before discovery. (_ is also in the alphabet but isn’t rejected — only - triggers it.) The tool-callback server is created on every launch_bridge, so every launch is exposed; the store-callback token has the same latent flaw when enabled.
Measured frequency
import secrets
n = 100_000
rate = sum(secrets.token_urlsafe(32).startswith(“-”) for _ in range(n)) / n
print(rate) # ~0.0153 → ~1 in 65 launches
Steps to Reproduce
import asyncio, secrets
import cursor_sdk._tool_callback as tc
from cursor_sdk import AsyncClient
Force a token that starts with ‘-’ (token_urlsafe yields this ~1.5% of the time)
tc._new_auth_token = lambda: “-” + secrets.token_urlsafe(31)
async def main():
client = await AsyncClient.launch_bridge(workspace=“.”, local={“cwd”: “.”})
await client.aclose()
asyncio.run(main()) # → “Missing value for --tool-callback-auth-token”
Expected Behavior
launch_bridge should never fail based on the value of a randomly generated internal token.
Operating System
MacOS
Version Information
cursor-sdk==0.1.7 (Python)
bundled bridge cursor-sdk-bridge package version 1.0.0
For AI issues: which model did you use?
Opus 4.8
Additional Information
Suggested fix (any one)
Generate parser-safe tokens (e.g. regenerate while the token starts with -, or use hex/token_hex); or
Pass the value as --tool-callback-auth-token= (and the same for --store-callback-auth-token); or
Make the bridge’s takeValue accept the next token as a value when the flag is known to take one, rather than rejecting any --prefixed string.
Workaround
Monkeypatch the token generators before launching the bridge to avoid a leading -:
import secrets
import cursor_sdk._tool_callback as tc, cursor_sdk._store_callback as sc
def _safe_token():
t = secrets.token_urlsafe(32)
while t.startswith(“-”):
t = secrets.token_urlsafe(32)
return t
tc._new_auth_token = sc._new_auth_token = _safe_token
Does this stop you from using Cursor
No - Cursor works, but with this issue