microsoft/typescript-go · error
Connection not established
Error message
Connection not established
What it means
Thrown by Client.apiRequest in the async API when, after the lazy connect() step, this.connection is still undefined. connect() sets connected and connection together on success, so in practice this throw indicates a race where close() ran concurrently (close() disposes the connection and clears both flags) or the spawn/socket setup resolved without ever creating the JSON-RPC connection.
Source
Thrown at _packages/native-preview/src/api/async/client.ts:170
const result = callback(arg as any);
if (name === "readFile") {
// readFile has 3 returns: string (content), null (not found), undefined (fall back).
// JSON-RPC can't distinguish null from undefined, so wrap in object.
if (result === undefined) return null;
return { content: result };
}
return result ?? null;
});
}
}
}
async apiRequest<T>(method: string, params?: unknown): Promise<T> {
if (!this.connected) {
await this.connect();
}
if (!this.connection) {
throw new Error("Connection not established");
}
const requestType = new RequestType<unknown, T, void>(method);
if (!this.timing) {
return this.connection.sendRequest(requestType, params);
}
// Round-trip latency is measured here; byte counts approximate the wire
// payload via the serialized JSON. Server-side processing time is not
// carried on the response; it is retrieved separately (via a
// getServerTiming request) and folded in by getTimingInfo().
const bytesSent = params === undefined ? 0 : Buffer.byteLength(JSON.stringify(params), "utf-8");
const start = performance.now();
const result = await this.connection.sendRequest(requestType, params);
const roundTripMs = performance.now() - start;
this.timing.record({
method,
roundTripMs,
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Await all in-flight requests before calling close(); sequence shutdown after quiescence
- Treat this error as 'client was closed': create a fresh API/Client and reconnect rather than reusing the instance
- Serialize API usage with a simple mutex/queue if requests and close() can race in your app
- Check client state before issuing requests in long-lived loops and stop when shut down
Example fix
// before
void api.parseConfigFile(file).catch(() => {});
await api.close(); // races the in-flight request -> 'Connection not established'
// after
await api.parseConfigFile(file); // drain work first
await api.close(); Defensive patterns
Strategy: retry
Validate before calling
// Ensure the client is connected (and not concurrently closed) before requesting
if (!client.isConnected && !isShuttingDown) {
await client.connect();
}
// Sequence shutdown elsewhere via a mutex so close() never overlaps requests Try / catch
try {
result = await client.apiRequest(method, params);
} catch (e) {
if (e instanceof Error && e.message === 'Connection not established') {
if (shuttingDown) return; // expected during teardown - skip
await client.connect();
result = await client.apiRequest(method, params); // retry once after reconnect
} else throw e;
} Prevention
- Await all in-flight requests before calling close()/API.close()
- Serialize requests vs. shutdown with a mutex or lifecycle flag
- Recreate the Client/API instance after close instead of resurrecting it
When it happens
Trigger: Calling close() (or API.close) while requests are still in flight: apiRequest passes the connected check, close() nulls this.connection, then apiRequest hits the second guard; a spawn whose 'spawn' event fired but connection creation failed; issuing requests immediately after close on the same Client instance.
Common situations: Fire-and-forget diagnostics not awaited before closing the API in scripts/tests; concurrent dispose and query in editor integrations; long-running watchers that keep requesting while another code path shuts the client down.
Related errors
- Cannot run a temporary file update on an inactive snapshot
- Snapshot is disposed
- Cannot create directory: a file already exists at "/${segmen
- Invalid file path: "${path}"
- Bad line number. Line: ${line}, lineStarts.length: ${lineSta
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/be0fa4a843b22227.
Report an issue: GitHub.