microsoft/typescript-go · error · Error
Language client is not initialized
Error message
Language client is not initialized
What it means
`Client.initializeAPISession` in _extension/src/client.ts lets other extensions get a direct pipe to the language server by sending the LSP request `custom/initializeAPISession`. The underlying vscode-languageclient `LanguageClient` is only constructed inside `Client.start()` (client.ts:205) and is torn down on stop, so calling this API before the session has started (or after it stopped) finds `this.client` undefined and throws this localized error.
Source
Thrown at _extension/src/client.ts:312
await Promise.all(disposables.map(d => d.dispose()));
await this.client?.dispose();
}
getCurrentExe(): { path: string; version: string; } | undefined {
return this.exe;
}
get serverPid(): number | undefined {
return (this.client as any)?._serverProcess?.pid;
}
/**
* Initialize an API session and return the socket path for connecting.
* This allows other extensions to get a direct connection to the API server.
*/
async initializeAPISession(pipe?: string): Promise<{ sessionId: string; pipe: string; }> {
if (!this.client) {
throw new Error(vscode.l10n.t("Language client is not initialized"));
}
return this.client.sendRequest<{ sessionId: string; pipe: string; }>("custom/initializeAPISession", { pipe });
}
/**
* Restart the language server if the executable path has not changed.
* Returns true if a restart was performed.
*/
async tryRestart(context: vscode.ExtensionContext): Promise<boolean> {
if (!this.client) {
return Promise.reject(new Error(vscode.l10n.t("Language client is not initialized")));
}
this.isStopping = false;
const exe = await getExe(context);
if (exe.path !== this.exe?.path) {
return false;
}
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Wait for readiness before calling: await the extension's activation completion and its initialized event / check the session's `isInitialized` state (client.ts:53)
- Wrap the call in try/catch and retry once after the initialized event fires, since startup is transient
- If it persists, check the TypeScript Native Preview output channel — the server may have failed to start (missing exe, crash), which leaves the client uninitialized
Example fix
// before const session = await tsNativePreview.initializeAPISession(); // throws during startup race // after await tsNativePreview.waitForInitialization?.() ?? waitUntil(() => tsNativePreview.isInitialized); const session = await tsNativePreview.initializeAPISession();
Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling the API, confirm the session is up
const ext = vscode.extensions.getExtension("typescript-native-preview")!;
await ext.activate();
if (!ext.exports?.isInitialized) {
// wait for the extension's initialized event or poll isInitialized before calling
await waitFor(() => ext.exports?.isInitialized === true, timeoutMs);
} Type guard
interface APISessionProvider {
isInitialized: boolean;
initializeAPISession(pipe?: string): Promise<{ sessionId: string; pipe: string }>;
}
function isReadySessionProvider(api: unknown): api is APISessionProvider {
return !!api && typeof (api as APISessionProvider).initializeAPISession === "function"
&& (api as APISessionProvider).isInitialized === true;
} Try / catch
try {
const session = await api.initializeAPISession();
} catch (e) {
if (e instanceof Error && /not initialized/i.test(e.message)) {
// transient startup race: wait for the initialized event, retry once
await onSessionInitialized();
const session = await api.initializeAPISession();
} else {
throw e; // real failure — surface it (check the output channel for server crashes)
}
} Prevention
- Always await the extension's activation and initialized event before using its exported API
- Treat 'not initialized' as retryable-once, not as a permanent condition
- In tests, start the Client before exercising initializeAPISession, and stop it in afterEach
When it happens
Trigger: Another extension calls `initializeAPISession()` during VS Code startup before the TypeScript Native Preview extension finished activation (exe download/launch), or after the session was stopped/restarted (e.g. user disabled it, or a config change triggered restart). The same guard also protects `tryRestart`.
Common situations: Extension-activation races — the consuming extension activates faster than the language server session; calling the exported API in tests without starting the client; the server crashed/stopped and the API is invoked while `client` is unset.
Related errors
- Invalid value for ${name}: ${value}
- forRelease requires setPrerelease unless nativePreviewReleas
- Unexpected number of arguments.
- Language server is not running.
- Could not find a TypeScript executable in the extension pack
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/c636f4ffa992e86a.
Report an issue: GitHub.