You are seeing quota limit errors or OAuth failures even on paid plans because the extension starts its language server without a valid auth token. The client is used before it is initialized, so the token never reaches the server and you appear logged out.
Fix OAuth failures and false quota limits caused by Language Server init order
The issue presents as broken authentication during startup. Typical logs show the client not ready, token propagation failing, and status updates breaking.
Example from affected sessions:
2026-01-24 21:46:36.769 [info] [Window] Started local extension host with pid 12873.
2026-01-24 21:46:37.365 [error] [Window] [Extension Host] Failed to update user status Error: LanguageServerClient must be initialized first!
2026-01-24 21:46:37.770 [info] (Antigravity) 2026-01-24 21:46:37.770 [INFO]: Language server started
2026-01-24 21:46:37.774 [info] W0124 21:46:37.764515 12909 client.go:137] failed to set auth token
2026-01-24 21:46:37.774 [info] W0124 21:46:37.765235 12909 log_context.go:106] Cache(userInfo): Singleflight refresh failed: You are not logged into Antigravity.
2026-01-24 21:46:37.774 [info] I0124 21:46:37.773667 12909 server.go:1504] initialized server successfully in 222.073667ms
What you should see after the fix:
2026-01-24 21:46:36.769 [info] [Window] Started local extension host with pid 12873.
2026-01-24 21:46:37.000 [info] [Window] [Extension Host] Initializing LanguageServerClient...
2026-01-24 21:46:37.200 [info] (Antigravity) 2026-01-24 21:46:37.200 [INFO]: Language server started
2026-01-24 21:46:37.250 [info] [Window] [Extension Host] LanguageServerClient initialized
2026-01-24 21:46:37.300 [info] [Window] [Extension Host] Authenticated session detected; setting auth token
2026-01-24 21:46:37.320 [info] I0124 21:46:37.320000 12909 client.go:137] auth token set
2026-01-24 21:46:37.350 [info] I0124 21:46:37.350000 12909 log_context.go:106] Cache(userInfo): refresh succeeded
2026-01-24 21:46:37.380 [info] [Window] [Extension Host] Starting update loop (user status / available models)
Init order bug. The extension uses the Language Server client before it is ready, so the auth token is never set on the server and the session looks unauthenticated.
Primary Fix
Initialize the client, wait for ready, then set the token and only after that start status or quota polling. Add retry and clear failure paths.
Complexity
Medium
Estimated Time
20 to 40 minutes for a code fix. 2 to 5 minutes for users to update and reauth.
Implement the correct init sequence to restore OAuth and quota
Step-by-Step Solution
1. Ensure the language client is fully ready before any auth or status logic
– Wait for the client ready signal and gate all code that depends on it.
– TypeScript example for a VS Code style extension:
“`
// create client once
const client = new LanguageClient(‘antigravityLS’, serverOptions, clientOptions);
// start the client early during activation
context.subscriptions.push(client.start());
// provide an explicit readiness gate
async function waitForClientReady(): Promise {
await client.onReady();
}
“`
2. Set the token only after the client is ready and confirm acknowledgment
– Push the token to the server after onReady and verify the server logs or response.
– Example:
“`
async function propagateAuthToken(token: string) {
await waitForClientReady();
try {
await client.sendRequest(‘antigravity/setAuthToken’, { token });
console.log(‘[Extension Host] Authenticated session detected; setting auth token’);
} catch (e) {
console.error(‘failed to set auth token’, e);
throw e;
}
}
“`
– On the server side you should see a message like:
“`
I0124 21:46:37.320000 12909 client.go:137] auth token set
“`
3. Start user status and model polling only after token acknowledgment
– Gate post login features behind a token set flag to avoid false quota errors:
“`
let tokenSet = false;
async function initAfterAuth() {
await propagateAuthToken(currentToken);
tokenSet = true;
startStatusPolling();
startModelRefresh();
}
function startStatusPolling() {
if (!tokenSet) return;
// begin timers or watchers here
}
“`
4. Add retry with backoff for transient token failures
– A small retry prevents races during process spawn:
“`
async function withRetry(fn: () => Promise, retries = 3, delayMs = 300) {
let lastErr;
for (let i = 0; i < retries; i++) {
try { return await fn(); } catch (e) { lastErr = e; }
await new Promise(r => setTimeout(r, delayMs * Math.pow(2, i)));
}
throw lastErr;
}
async function safePropagateAuthToken(token: string) {
await withRetry(() => propagateAuthToken(token));
}
“`
5. Prevent early consumers from touching the client before ready
– Short circuit features that depend on the language server if the client is not ready yet:
“`
function requireClientReady() {
if (!client.needsStop() && !client.isRunning()) {
throw new Error(‘LanguageServerClient must be initialized first!’);
}
}
// call requireClientReady() inside commands that use the client
“`
6. For users update and reauthenticate to pick up the fix
– Update the extension and reload:
“`
# List current version
code –list-extensions –show-versions | grep -i antigravity
# Install or update to the latest
code –install-extension vendor.antigravity
“`
– Sign out and sign back in through the extension UI, then reload the window.
– Verify logs show the good sequence above and that quota checks no longer fail.
If your workspace still reports limits after this fix, see resolving sudden quota reductions for additional checks.
Alternative Fixes and Workarounds
Force a delayed start of status polling
– Temporarily guard status loops with a fixed readiness promise to avoid touching the client too early. Replace with the proper onReady gate in the main fix.
Add an activation event that guarantees the client starts before commands
– Ensure activation events initialize the client so user commands cannot run before readiness. See the VS Code activation model in the language server guide: Language Server extension guide.
Roll back to a known good build
– If production is blocked, install a previous extension version while you ship the patch:
“`
code –install-extension vendor.antigravity@x.y.z
“`
For a related production incident analysis and what changed between builds, see this quota incident case.
Troubleshooting Tips
Confirm the exact error messages
– Look for lines like Failed to update user status Error: LanguageServerClient must be initialized first! and failed to set auth token. These confirm the race.
Check server acknowledgment
– Absence of auth token set in server logs means the token never arrived.
Validate OAuth session health
– If the browser session expired, reauthenticate. Reference OAuth basics if needed: OAuth 2.0 RFC 6749.
Watch for concurrent refresh edge cases
– Singleflight messages indicate deduped refreshes. Ensure only one refresh runs and that it follows a successful token set. See Go singleflight pattern: singleflight.
Network and clock sanity
– Proxy or strict firewall rules can block token exchange. System clock drift can also break OAuth validation.
Best Practices
Always wait for the client to be ready before any RPCs that depend on it.
Propagate auth once, verify acknowledgment, then start periodic tasks.
Centralize token flow and guard consumer features behind a token ready flag.
Add integration tests that assert the correct sequence from logs and events.
Emit clear telemetry and log points for init start, ready, token set, and poll start.
Provide a manual reconnect command that replays the token and restarts polling.
The real fix is ordering. Initialize the client, set the token after ready, and only then start anything that queries user status or quota. With that sequence restored, OAuth works and false quota limits disappear.
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.