{"record":{"id":"c6bff888107efaba","repo":"honojs/hono","slug":"env-has-to-include-the-2nd-argument-of-fetch","errorCode":null,"errorMessage":"env has to include the 2nd argument of fetch.","messagePattern":"env has to include the 2nd argument of fetch\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/adapter/bun/conninfo.ts","lineNumber":20,"sourceCode":"import type { GetConnInfo } from '../../helper/conninfo'\nimport { getBunServer } from './server'\n\n/**\n * Get ConnInfo with Bun\n * @param c Context\n * @returns ConnInfo\n */\nexport const getConnInfo: GetConnInfo = (c: Context) => {\n  const server = getBunServer<{\n    requestIP?: (req: Request) => {\n      address: string\n      family: string\n      port: number\n    } | null\n  }>(c)\n\n  if (!server) {\n    throw new TypeError('env has to include the 2nd argument of fetch.')\n  }\n  if (typeof server.requestIP !== 'function') {\n    throw new TypeError('server.requestIP is not a function.')\n  }\n\n  // https://bun.sh/docs/runtime/http/server#server-requestip-request\n  // Returns null for closed requests or Unix domain sockets.\n  const info = server.requestIP(c.req.raw)\n\n  if (!info) {\n    return {\n      remote: {},\n    }\n  }\n\n  return {\n    remote: {\n      address: info.address,","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/adapter/bun/conninfo.ts#L2-L38","documentation":"Hono's Bun adapter getConnInfo() needs access to the Bun `Server` object that served the request. On Bun, that server instance is only available when Hono is mounted via `Bun.serve({ fetch: app.fetch, ... })` — Bun passes the server as the second argument of fetch(), and Hono stores it in `c.env`. If getConnInfo() is called outside that setup, `c.env.server` is undefined and this TypeError is thrown.","triggerScenarios":"Calling `getConnInfo(c)` from `hono/bun` when the app was not registered as the `fetch` handler of `Bun.serve()` (e.g. using `app.fetch` standalone, running under Node.js/deno, or a custom fetch wrapper that drops Bun's second `server` argument), so `c.env.server` is falsy.","commonSituations":"Porting a Hono app from Node (via @hono/node-server) to Bun and forgetting to switch to `Bun.serve({ fetch: app.fetch })`; unit tests calling handlers with `app.request()` where no Bun server exists; wrapping app.fetch in a closure like `(req) => app.fetch(req)` which discards the `server` parameter.","solutions":["Mount the app correctly for Bun: `const server = Bun.serve({ fetch: app.fetch, port: 3000 })` so Bun injects the server into c.env","If you wrap fetch, forward all arguments: `Bun.serve({ fetch: (...args) => app.fetch(...args) })`","Guard before calling: check `getConnInfo` is only used inside a real Bun.serve request, e.g. wrap in try/catch or feature-detect the runtime","In tests, call getConnInfo only against a real Bun.serve instance, not app.request()"],"exampleFix":"// before\nconst app = new Hono()\napp.get((c) => c.json({ ip: getConnInfo(c).remote.address }))\n// started in a way that drops Bun's server arg\nBun.serve({ fetch: (req) => app.fetch(req) }) // throws\n\n// after\nBun.serve({ fetch: app.fetch, port: 3000 }) // Bun passes (req, server) -> c.env.server","handlingStrategy":"validation","validationCode":"import { getConnInfo } from 'hono/bun'\n\nfunction hasBunServer(c: Context): boolean {\n  return Boolean((c.env as any)?.server)\n}\n\napp.get('/ip', (c) => {\n  if (!hasBunServer(c)) return c.text('ip unavailable', 200)\n  return c.json(getConnInfo(c))\n})","typeGuard":"const isBunServerEnv = (\n  env: unknown\n): env is { server: { requestIP(req: Request): { address: string; family: string; port: number } } } =>\n  typeof (env as any)?.server?.requestIP === 'function'","tryCatchPattern":"try { const info = getConnInfo(c) } catch (e) { if (e instanceof TypeError && e.message.startsWith('env has to include')) { /* fall back to x-forwarded-for */ } else throw e }","preventionTips":["Always mount Hono as Bun.serve({ fetch: app.fetch }) so Bun injects the server","Forward all fetch args in wrappers: (...args) => app.fetch(...args)","Feature-detect c.env.server before calling getConnInfo in code shared across runtimes"],"tags":["bun","adapter","conninfo","ip-address","runtime"],"backgroundTag":"missing-runtime-context","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}