hcengineering/platform · error
Client ${clientId} not found
Error message
Client ${clientId} not found What it means
BackRPC server's request() sends a back-channel RPC request to a connected client, but the given clientId has no mapping to an underlying transport identity. The server throws because it cannot route the request to an unknown client. This indicates the client was never connected, or has since disconnected and been removed from clientMapping.
Source
Thrown at foundations/net/packages/backrpc/src/server.ts:314
const { message, stack } = parseJSON(payload.toString())
req?.reject(new Error(message + '\n' + stack))
} catch (err: any) {
console.error(err)
}
this.backRequests.delete(reqID)
break
}
}
} catch (err: any) {
console.error(err)
}
}
}
async request (clientId: ClientT, method: string, params: any): Promise<any> {
const clientIdentity = this.clientMapping.get(clientId)
if (clientIdentity === undefined) {
throw new Error(`Client ${clientId} not found`)
}
return await new Promise<any>((resolve, reject) => {
const reqId = clientId + '-' + this.requestCounter++
this.backRequests.set(reqId, { resolve, reject })
void this.doSend([clientIdentity, backrpcOperations.request, reqId, stringifyJSON([method, params])]).catch(
(err) => {
reject(err)
}
)
})
}
async send (clientId: ClientT, body: any): Promise<any> {
const clientIdentity = this.clientMapping.get(clientId)
if (clientIdentity === undefined) {
throw new Error(`Client ${clientId as string} not found`)
}View on GitHub (pinned to 63e28dc964)
Solutions
- Verify the clientId exists before calling request by tracking registrations from the hello/handshake path
- Reconnect or re-handshake the client to obtain a fresh clientId and retry
- Handle the thrown error by removing the stale client reference from caller state
- Check for client disconnects between obtaining the clientId and issuing the request
Example fix
// before
await server.request(clientId, 'op', params) // throws if client gone
// after
if (server.hasClient(clientId)) { // track registration yourself if no such helper
await server.request(clientId, 'op', params)
} else {
await reconnectAndRetry(clientId)
} Defensive patterns
Strategy: try-catch
Validate before calling
// maintain your own registry of live clientIds
function isClientLive(clientId: string): boolean {
return liveClients.has(clientId)
} Type guard
function hasClient(mapping: Map<ClientT, unknown>, clientId: ClientT): clientId is ClientT {
return mapping.has(clientId)
} Try / catch
try {
await server.request(clientId, method, params)
} catch (e) {
if (e instanceof Error && e.message === `Client ${clientId} not found`) {
dropStaleClient(clientId)
} else { throw e }
} Prevention
- Register clientIds only from the hello/handshake path
- Remove clientIds on disconnect events
- Never cache clientIds across server restarts
- Log client lifetimes to spot races
When it happens
Trigger: Calling server.request(clientId, method, params) with a clientId that was never registered via hello, or whose connection was closed and pruned from clientMapping before the call.
Common situations: Race after client disconnect: caller holds a stale clientId from an earlier session and sends a request; load-balanced setup where the request lands on a server instance the client never connected to; client restart produced a new UUID.
Related errors
- Client ${clientId as string} not found
- Wrong video options specified
- platform.status.ConnectionClosed
- HTTP error ${res.status}
- result.error
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/94d09d82ea49a01b.
Report an issue: GitHub.