vitejs/vite · error · SendBeforeConnectError
invoke was called before connect
Error message
invoke was called before connect
What it means
Thrown by the normalized transport's invoke() when called before connect() has completed and there is no in-flight connecting promise. invoke() needs the transport to be connected so the RPC request/response round-trip can complete; invoking earlier rejects immediately.
Solutions
- Await transport.connect() before any invoke call.
- Let the ModuleRunner own connection lifecycle — avoid calling transport.invoke manually outside the runner.
- Catch SendBeforeConnectError (error.name === 'SendBeforeConnectError') and retry once connect resolves.
Example fix
// before
const res = await transport.invoke('fetchModule', [id]) // throws if not connected
// after
await transport.connect()
const res = await transport.invoke('fetchModule', [id]) Defensive patterns
Strategy: validation
Validate before calling
await transport.connect() await transport.invoke(name, data)
Try / catch
try {
await transport.invoke(name, data)
} catch (e) {
if (e?.name === 'SendBeforeConnectError') {
await transport.connect()
await transport.invoke(name, data)
} else throw e
} Prevention
- Await connect() before any invoke call.
- Route RPC through the ModuleRunner rather than calling transport.invoke directly.
When it happens
Trigger: Calling transport.invoke(name, data) before awaiting transport.connect(). Throws SendBeforeConnectError at moduleRunnerTransport.ts:250 under the same conditions as the send guard.
Common situations: Custom runner bootstrap that issues an RPC immediately. Calling invoke during construction before the WebSocket/emitter is ready. Forgetting to await an async connect in setup.
Related errors
- send was called before connect
- Cannot send non-custom events from the client to the server.
- Cannot send non-custom events from the server to the client.
- HMR is not supported by this runner transport, but `hmr`…
- [module runner] Failed to load
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/b2c0391291269a7f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vite/src/shared/moduleRunnerTransport.ts:250
: {}),
async send(data) {
if (!invokeableTransport.send) return
if (!isConnected) {
if (connectingPromise) {
await connectingPromise
} else {
throw new SendBeforeConnectError('send was called before connect')
}
}
await invokeableTransport.send(data)
},
async invoke(name, data) {
if (!isConnected) {
if (connectingPromise) {
await connectingPromise
} else {
throw new SendBeforeConnectError('invoke was called before connect')
}
}
return invokeableTransport.invoke(name, data)
},
}
}
export class SendBeforeConnectError extends Error {
constructor(message: string) {
super(message)
this.name = 'SendBeforeConnectError'
}
}
export const createWebSocketModuleRunnerTransport = (options: {
// eslint-disable-next-line n/no-unsupported-features/node-builtins
createConnection: () => WebSocket
pingInterval?: numberView on GitHub (pinned to b4d66fee14)