{"record":{"id":"1b46a0d06411dfce","repo":"vitejs/vite","slug":"cannot-send-non-custom-events-from-the-client-to-t","errorCode":null,"errorMessage":"Cannot send non-custom events from the client to the server.","messagePattern":"Cannot send non-custom events from the client to the server\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/ssr/runtime/serverModuleRunner.ts","lineNumber":93,"sourceCode":"    }\n    if (typeof options.sourcemapInterceptor === 'object') {\n      return { ...prepareStackTrace, ...options.sourcemapInterceptor }\n    }\n    return options.sourcemapInterceptor\n  }\n  if (typeof process !== 'undefined' && 'setSourceMapsEnabled' in process) {\n    return 'node'\n  }\n  return prepareStackTrace\n}\n\nexport const createServerModuleRunnerTransport = (options: {\n  channel: NormalizedServerHotChannel\n}): ModuleRunnerTransport => {\n  const hmrClient: HotChannelClient = {\n    send: (payload: HotPayload) => {\n      if (payload.type !== 'custom') {\n        throw new Error(\n          'Cannot send non-custom events from the client to the server.',\n        )\n      }\n      options.channel.send(payload)\n    },\n  }\n\n  let handler: ((data: HotPayload) => void) | undefined\n\n  return {\n    connect({ onMessage }) {\n      options.channel.api!.outsideEmitter.on('send', onMessage)\n      options.channel.api!.innerEmitter.emit(\n        'vite:client:connect',\n        undefined,\n        hmrClient,\n      )\n      onMessage({ type: 'connected' })","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/ssr/runtime/serverModuleRunner.ts#L75-L111","documentation":"Thrown by the server module runner transport's client-side send() when the payload type is not 'custom'. The server-side ModuleRunner transport only permits custom events (user/plugin-defined) from the running module back to the dev server; built-in HMR payloads like 'update'/'connected' are server-to-client only.","triggerScenarios":"Code in an SSR module runner calling something that emits a non-custom HotPayload (e.g. import.meta.hot.send with a reserved type, or an internal HMR API misused). The guard is `if (payload.type !== 'custom')` at serverModuleRunner.ts:92.","commonSituations":"A plugin or framework trying to push HMR update/connected payloads from the runner to the server. Misusing import.meta.hot.send (which is meant for custom events) with a built-in payload type. Internal Vite bug where a non-custom payload is routed through this transport.","solutions":["Use import.meta.hot.send('my-custom-event', data) — only custom event names are allowed over this transport.","Do not attempt to emit 'update'/'connected'/'prune' payloads from the runner; those are managed by Vite itself.","If this fires from framework code, route the message through a custom event and have the server side listen via server.hot.on(event)."],"exampleFix":"// before\nhot.send({ type: 'update', updates: [...] }) // throws\n// after\nhot.send('my-framework-event', { payload })","handlingStrategy":"validation","validationCode":"// only emit custom events from the runner\nhot.send('my-custom-event', data)","typeGuard":"function isCustomPayload(p: HotPayload): boolean {\n  return p.type === 'custom'\n}","tryCatchPattern":null,"preventionTips":["Treat import.meta.hot.send as custom-event only; never build 'update'/'connected' payloads yourself.","Use transport.invoke for RPC rather than hand-rolling payload types."],"tags":["ssr","module-runner","hmr","transport"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}