{"record":{"id":"c00ecbe4d40fd059","repo":"honojs/hono","slug":"failed-to-upgrade-websocket","errorCode":null,"errorMessage":"Failed to upgrade WebSocket","messagePattern":"Failed to upgrade WebSocket","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/helper/websocket/index.ts","lineNumber":134,"sourceCode":"      | [createEvents: (c: Context) => WSEvents<T> | Promise<WSEvents<T>>, options?: U]\n      | [c: Context, events: WSEvents<T>, options?: U]\n  ) => {\n    if (typeof args[0] === 'function') {\n      const [createEvents, options] = args\n      return async function upgradeWebSocket(c, next) {\n        const events = await createEvents(c)\n        const result = await handler(c, events, options as U)\n        if (result) {\n          return result\n        }\n        await next()\n      }\n    } else {\n      const [c, events, options] = args as [c: Context, events: WSEvents<T>, options?: U]\n      return (async () => {\n        const upgraded = await handler(c, events, options as U)\n        if (!upgraded) {\n          throw new Error('Failed to upgrade WebSocket')\n        }\n        return upgraded\n      })()\n    }\n  }) as UpgradeWebSocket<T, U>\n}\n","sourceCodeStart":116,"sourceCodeEnd":141,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/helper/websocket/index.ts#L116-L141","documentation":"defineWebSocketHelper wraps runtime-specific WebSocket upgrade handlers. In the three-argument form (Context, events, options) it awaits the handler and, if the handler returns a falsy value (the upgrade did not succeed), throws this generic Error indicating the HTTP->WebSocket upgrade was rejected.","triggerScenarios":"A WebSocket route using upgradeWebSocket() where the underlying runtime handler returns falsy: Bun upgrade() failing (c.env.server missing — see Bun env error), wrong route/method, subprotocol/version mismatch, or handler returning undefined instead of a Response/context.","commonSituations":"Bun/Node adapter mismatch (using the wrong runtime's WS helper); app not mounted via the expected server (Bun.serve) so upgrade can't run; request not actually a WebSocket upgrade (missing Upgrade header); testing WS routes with plain app.request() without upgrade headers.","solutions":["Check the runtime/adapter pairing: use createBunWebSocket on Bun.serve, @hono/node-server's WS helper on Node, and the Cloudflare/Deno helpers accordingly","Ensure the app is the direct fetch handler of the runtime server so upgrade machinery is available","Verify the client sends a real WebSocket upgrade request (Upgrade: websocket, Sec-WebSocket-Key headers) to the WS route","In tests use the runtime's WS test utilities (e.g. @hono/node-server createAdaptorServer + ws client), not app.request()"],"exampleFix":"// before\nimport { createBunWebSocket } from 'hono/bun'\n// but app served by @hono/node-server -> handler returns falsy -> throws\n\n// after (Node)\nimport { createNodeWebSocket } from '@hono/node-server'\nconst { injectWebSocket, upgradeWebSocket } = createNodeWebSocket(app)\nconst server = serve({ fetch: app.fetch })\ninjectWebSocket(server)","handlingStrategy":"try-catch","validationCode":"const isUpgradeRequest = (c: Context) =>\n  c.req.header('upgrade')?.toLowerCase() === 'websocket' &&\n  !!c.req.header('sec-websocket-key')\n\napp.get('/ws', (c) => {\n  if (!isUpgradeRequest(c)) return c.text('WebSocket endpoint', 426)\n  return upgradeWebSocket(handler)(c)\n})","typeGuard":"const isUpgradeRequest = (c: { req: { header(k: string): string | undefined } }): boolean =>\n  c.req.header('upgrade')?.toLowerCase() === 'websocket'","tryCatchPattern":"try { return await upgradeWebSocket(handler)(c, events) } catch (e) { if (e instanceof Error && e.message === 'Failed to upgrade WebSocket') return c.text('upgrade failed', 500); throw e }","preventionTips":["Match the WebSocket helper to your runtime/adapter (Bun vs Node vs Workers)","Serve the app through the runtime's own server so upgrade() exists","Test WS routes with real upgrade headers or runtime WS test helpers"],"tags":["websocket","upgrade","adapter","runtime","hono"],"backgroundTag":"websocket-upgrade-failed","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}