hcengineering/platform · error
Router is not bound to a port
Error message
Router is not bound to a port
What it means
backrpc Server.getPort() parses the port from router.lastEndpoint via the regex /:(\d+)$/. If the endpoint string doesn't end in `:<port>` (e.g. a Unix socket path, named pipe, or port-0 style endpoint), parseInt yields undefined and the server throws because it cannot determine a TCP port. The endpoint is bound, but not to a numeric port.
Source
Thrown at foundations/net/packages/backrpc/src/server.ts:125
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 {
await this.sendPromise
} catch (err: any) {
console.error('Failed to send message', err)
}
this.sendPromise = undefined
}View on GitHub (pinned to 63e28dc964)
Solutions
- Bind the router to a TCP endpoint with an explicit numeric port (e.g. host:port form ending in :8080).
- If using a Unix socket/named pipe, read the socket path from the endpoint instead of calling getPort().
- Check the lastEndpoint string format your transport produces and match the /:(\d+)$/ expectation.
- Specify a concrete port in configuration rather than an ephemeral or implicit one.
Example fix
// before: bound to a unix socket, getPort() can't parse a port
const server = new Server({ endpoint: 'unix:/tmp/backrpc.sock' });
const port = await server.getPort(); // throws
// after: bind to TCP with an explicit port
const server = new Server({ endpoint: '127.0.0.1:8080' });
const port = await server.getPort(); // 8080 Defensive patterns
Strategy: type-guard
Validate before calling
function isTcpEndpoint(ep) { return typeof ep === 'string' && /:(\d+)$/.test(ep); }
// only call getPort() when the bound endpoint is TCP
if (isTcpEndpoint(server.router.lastEndpoint)) { await server.getPort(); } Type guard
function hasTcpEndpoint(server) {
const ep = server.router?.lastEndpoint;
return typeof ep === 'string' && /:(\d+)$/.test(ep);
} Try / catch
try {
const port = await server.getPort();
} catch (e) {
if (e.message === 'Router is not bound to a port') {
// endpoint exists but is not TCP (e.g. unix socket) — use the path instead
const socketPath = server.router.lastEndpoint;
console.log('Non-TCP endpoint:', socketPath);
} else throw e;
} Prevention
- Use getPort() only for TCP endpoints; read socket paths directly for unix-socket transports.
- Configure explicit host:port endpoints when a port is needed.
- Check the endpoint format (trailing :port) before requesting a port.
When it happens
Trigger: Router bound to a non-TCP endpoint (Unix domain socket, named pipe) or an endpoint string without a trailing `:digits`, then calling getPort().
Common situations: Configuring the transport with a unix:/path-to-socket endpoint and then asking for a TCP port; binding to port 0 or a hostname-only endpoint; transport writing lastEndpoint in a format the regex doesn't match.
Related errors
- Router is not bound to an endpoint
- 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/ddff375af689939b.
Report an issue: GitHub.