hcengineering/platform · error · PlatformError
ConnectionClosed
Error message
ConnectionClosed
What it means
sendRequest throws a PlatformError with status ConnectionClosed when a request is attempted on a client connection that has already been closed. The library guards the request path so callers never wait on a socket that will never answer. Any RPC (including pings and model loads) issued after close fails immediately with this error.
Source
Thrown at plugins/client-resources/src/connection.ts:685
}
private sendRequest (data: {
method: string
params: any[]
// If not defined, on reconnect with timeout, will retry automatically.
retry?: () => Promise<boolean>
handleResult?: (result: any) => Promise<void>
once?: boolean // Require handleResult to retrieve result
measure?: (time: number, result: any, serverTime: number, queue: number, toRecieve: number) => void
allowReconnect?: boolean
overrideId?: number
}): Promise<any> {
return this.ctx.with(
'send-request',
{},
async (ctx) => {
if (this.closed) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.ConnectionClosed, {}))
}
if (this.slowDownTimer > 0) {
// We need to wait a bit to avoid ban.
await new Promise((resolve) => setTimeout(resolve, this.slowDownTimer))
}
if (data.once === true) {
// Check if has same request already then skip
const dparams = JSON.stringify(data.params)
for (const [, v] of this.requests) {
if (v.method === data.method && JSON.stringify(v.params) === dparams) {
// We have same unanswered, do not add one more.
return
}
}
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Check client/connection closed state before issuing requests and re-create the connection if closed
- Wrap request calls in retry logic that reopens the connection on ConnectionClosed
- Avoid closing the connection while async operations are still pending; await them first
- Reconnect and re-authenticate on this error, since the old connection cannot be reused
Example fix
// before const model = await client.loadModel() // after if (connection.closed) await reconnect() const model = await client.loadModel()
Defensive patterns
Strategy: retry
Validate before calling
if (connection.closed) { await reconnect(connection) } Type guard
function isConnectionClosed(err: unknown): boolean {
return err instanceof PlatformError && err.status.status === platform.status.ConnectionClosed
} Try / catch
try {
await client.loadModel()
} catch (err) {
if (isConnectionClosed(err)) {
await reconnect(connection)
return client.loadModel()
}
throw err
} Prevention
- Check this.closed / connection state before issuing requests
- Serialize close() so it never runs while requests are pending
- Implement automatic reconnect-and-retry on ConnectionClosed
- Watch connection lifecycle events to invalidate queued operations early
When it happens
Trigger: Calling any client API (loadModel, getAccount, schedulePing, handleMsg-triggered requests, checkArrayBufferPing) after connection.close() was invoked or this.closed was set true; racing a close() against in-flight operations.
Common situations: App shutdown or page unload closing the connection while background requests are pending; reconnect logic issuing requests on a stale closed client instance; timeout handlers closing the connection while a loadModel/getAccount call is in flight.
Related errors
- platform.status.ConnectionClosed
- "npm view" returned error code ${npmVersionSpawnResult.statu
- Unable to resolve version ${version} of package ${name}: ${e
- response.statusText
- "npm view" returned error code ${npmVersionSpawnResult.statu
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/969d8f9f4a4531a0.
Report an issue: GitHub.