honojs/hono · error · TypeError

server.requestIP is not a function.

Error message

server.requestIP is not a function.

What it means

getConnInfo() in the Bun adapter retrieves the client's address via Bun's server.requestIP(request) API. This error means the object found in `c.env.server` exists but does not expose a `requestIP` function — typically because the app was mounted through a non-Bun server (e.g. @hono/node-server also populates env with a server-like object) or the Bun version/runtime is one where requestIP is unavailable.

Source

Thrown at src/adapter/bun/conninfo.ts:23

/**
 * Get ConnInfo with Bun
 * @param c Context
 * @returns ConnInfo
 */
export const getConnInfo: GetConnInfo = (c: Context) => {
  const server = getBunServer<{
    requestIP?: (req: Request) => {
      address: string
      family: string
      port: number
    } | null
  }>(c)

  if (!server) {
    throw new TypeError('env has to include the 2nd argument of fetch.')
  }
  if (typeof server.requestIP !== 'function') {
    throw new TypeError('server.requestIP is not a function.')
  }

  // https://bun.sh/docs/runtime/http/server#server-requestip-request
  // Returns null for closed requests or Unix domain sockets.
  const info = server.requestIP(c.req.raw)

  if (!info) {
    return {
      remote: {},
    }
  }

  return {
    remote: {
      address: info.address,
      addressType: info.family === 'IPv6' || info.family === 'IPv4' ? info.family : undefined,
      port: info.port,
    },

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Import getConnInfo from the adapter matching your runtime: 'hono/bun' for Bun.serve, '@hono/node-server/conninfo' for Node
  2. Upgrade Bun to a version supporting server.requestIP (bun upgrade)
  3. Verify you actually start the app with Bun.serve({ fetch: app.fetch }) and not another server
  4. Feature-detect before calling: `if (typeof server?.requestIP === 'function')` or wrap in try/catch and fall back to x-forwarded-for

Example fix

// before
import { getConnInfo } from 'hono/bun' // but served via @hono/node-server
const info = getConnInfo(c)

// after (Node)
import { serve } from '@hono/node-server'
import { getConnInfo } from '@hono/node-server/conninfo'
serve({ fetch: app.fetch })
const info = getConnInfo(c)
Defensive patterns

Strategy: type-guard

Validate before calling

const canGetConnInfo = (c: Context) =>
  typeof (c.env as any)?.server?.requestIP === 'function'

app.get('/ip', (c) => canGetConnInfo(c) ? c.json(getConnInfo(c)) : c.text('n/a'))

Type guard

const supportsRequestIP = (env: unknown): env is { server: { requestIP(r: Request): unknown } } =>
  typeof (env as any)?.server?.requestIP === 'function'

Try / catch

try { info = getConnInfo(c) } catch { info = parseXFF(c.req.header('x-forwarded-for')) }

Prevention

When it happens

Trigger: Calling `getConnInfo(c)` from 'hono/bun' where `c.env.server` is present (Bun.serve was used or another adapter injected a server object) but that object lacks a `requestIP` method — e.g. running the Bun adapter code under Node with @hono/node-server, or an outdated/mismatched Bun runtime.

Common situations: Mixing adapters: importing getConnInfo from 'hono/bun' while serving with @hono/node-server; CI running tests under Node while the code assumes Bun; very old Bun versions before requestIP was added; custom objects placed in c.env that shadow the expected server shape.

Related errors


AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28). Data as JSON: /api/errors/3b18f2311fabf982. Report an issue: GitHub.