hcengineering/platform · error
Router is not bound to an endpoint
Error message
Router is not bound to an endpoint
What it means
backrpc Server.getPort() waits for the server's bound promise, then reads router.lastEndpoint. If the router still has no endpoint (null), the router never actually bound to a socket even though binding resolved, so the server cannot report a port. This guards against reporting a port for an unbound router.
Source
Thrown at foundations/net/packages/backrpc/src/server.ts:119
)
this.handleClose(clientRecord.id, clientId, true)
}
}
}
private handleClose (clientRecordId: ClientT, clientId: string, timeout: boolean): void {
void this.handlers.closeHandler?.(clientRecordId, timeout).catch((err) => {
console.error('Error in handleTimeout', err)
})
this.revClientMapping.delete(clientId)
this.clientMapping.delete(clientRecordId)
}
async getPort (): Promise<number> {
await this.bound
const reqEndpoint = this.router.lastEndpoint
if (reqEndpoint === null) {
throw new Error('Router is not bound to an endpoint')
}
const portMatch = reqEndpoint.match(/:(\d+)$/)
const port = portMatch != null ? parseInt(portMatch[1]) : undefined
if (port === undefined) {
throw new Error('Router is not bound to a port')
}
return port
}
private sendPromise: Promise<void> | undefined
async doSend (msg: any[]): Promise<void> {
while (this.sendPromise !== undefined) {
await this.sendPromise
}
this.sendPromise = this.router.send(msg)
try {View on GitHub (pinned to 63e28dc964)
Solutions
- Ensure the server is fully started (call the start/listen method and await it) before calling getPort().
- Inspect the transport implementation: verify bind() sets router.lastEndpoint before resolving its promise.
- Log router.lastEndpoint right after startup to confirm the endpoint is set in your environment.
- If the server may be closed, re-create/rebind it before querying the port.
Example fix
// before await server.bound; const port = await server.getPort(); // throws: endpoint null // after await server.start(); // actually binds the router const port = await server.getPort();
Defensive patterns
Strategy: try-catch
Try / catch
try {
const port = await server.getPort();
} catch (e) {
if (e.message === 'Router is not bound to an endpoint') {
throw new Error('Server startup incomplete: await server.start() before getPort()');
}
throw e;
} Prevention
- Always await the server's full start/listen call, not just the bound promise, before querying the port.
- Assert router.lastEndpoint !== null after startup in smoke tests.
- Avoid closing the server before reading its port.
When it happens
Trigger: Calling server.getPort() after awaiting this.bound when router.lastEndpoint is null — i.e. the transport/router bound promise resolved without establishing an endpoint, typically because listen/bind was never called or bound to nothing.
Common situations: Calling getPort() before start()/listen() has really attached the router to an endpoint; a transport implementation whose bind resolves without setting lastEndpoint; race where the server was closed between bind and getPort.
Related errors
- Router is not bound to a port
- Message id is required
- platform.status.ConnectionClosed
- HTTP error ${res.status}
- result.error
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/e73d9b070023a5c6.
Report an issue: GitHub.