{"record":{"id":"b0bb8f464c398d31","repo":"vitejs/vite","slug":"send-was-called-before-connect","errorCode":null,"errorMessage":"send was called before connect","messagePattern":"send was called before connect","errorType":"exception","errorClass":"SendBeforeConnectError","httpStatus":null,"severity":"error","filePath":"packages/vite/src/shared/moduleRunnerTransport.ts","lineNumber":240,"sourceCode":"      ? {\n          async disconnect() {\n            if (!isConnected) return\n            if (connectingPromise) {\n              await connectingPromise\n            }\n            isConnected = false\n            await invokeableTransport.disconnect!()\n          },\n        }\n      : {}),\n    async send(data) {\n      if (!invokeableTransport.send) return\n\n      if (!isConnected) {\n        if (connectingPromise) {\n          await connectingPromise\n        } else {\n          throw new SendBeforeConnectError('send was called before connect')\n        }\n      }\n      await invokeableTransport.send(data)\n    },\n    async invoke(name, data) {\n      if (!isConnected) {\n        if (connectingPromise) {\n          await connectingPromise\n        } else {\n          throw new SendBeforeConnectError('invoke was called before connect')\n        }\n      }\n      return invokeableTransport.invoke(name, data)\n    },\n  }\n}\n\nexport class SendBeforeConnectError extends Error {","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/shared/moduleRunnerTransport.ts#L222-L258","documentation":"Thrown by the normalized transport's send() when it is invoked before connect() has completed, with no in-flight connecting promise. The transport tracks an isConnected flag set only after connect resolves; sending earlier means messages would be dropped.","triggerScenarios":"Calling transport.send(payload) before awaiting transport.connect(). Throws SendBeforeConnectError at moduleRunnerTransport.ts:240 when isConnected is false and there is no connectingPromise.","commonSituations":"Custom code that constructs a runner/transport and immediately sends without waiting for connect. A race where the module runner is asked to fetch before the WebSocket/emitter connection is established. Forgetting to await an async connect in a bootstrap sequence.","solutions":["Always await transport.connect() (or runner's underlying connect) before sending.","If using the ModuleRunner, ensure the runner is connected before importing modules — the runner normally manages this, so avoid calling transport.send manually.","Catch SendBeforeConnectError (error.name === 'SendBeforeConnectError') and retry after awaiting connect."],"exampleFix":"// before\ntransport.send({ type: 'custom', event: 'ping', data: {} }) // throws if not connected\n// after\nawait transport.connect()\ntransport.send({ type: 'custom', event: 'ping', data: {} })","handlingStrategy":"validation","validationCode":"await transport.connect()\nawait transport.send(payload)","typeGuard":null,"tryCatchPattern":"try {\n  await transport.send(payload)\n} catch (e) {\n  if (e?.name === 'SendBeforeConnectError') {\n    await transport.connect()\n    await transport.send(payload)\n  } else throw e\n}","preventionTips":["Always await connect() before send().","Let the ModuleRunner manage connect lifecycle; avoid manual transport.send."],"tags":["module-runner","transport","lifecycle"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}