honojs/hono · error · Error

Error processing response: ${error instanceof Error ? error.

Error message

Error processing response: ${error instanceof Error ? error.message : 'Unknown error'}

What it means

The SSG (Static Site Generation) helper reads the body of each fetched route response to save it to disk. parseResponseContent tries response.text() for text/json content types and response.arrayBuffer() otherwise; if reading the body throws (stream error, aborted fetch, unsupported type), it wraps the underlying failure in this generic Error.

Source

Thrown at src/helper/ssg/ssg.ts:84

    filePath = joinPaths(outDir, `${routePath}.${extension}`)
  }

  ensureWithinOutDir(outDir, filePath)

  return filePath
}

const parseResponseContent = async (response: Response): Promise<string | ArrayBuffer> => {
  const contentType = response.headers.get('Content-Type')

  try {
    if (contentType?.includes('text') || contentType?.includes('json')) {
      return await response.text()
    } else {
      return await response.arrayBuffer()
    }
  } catch (error) {
    throw new Error(
      `Error processing response: ${error instanceof Error ? error.message : 'Unknown error'}`
    )
  }
}

export const defaultExtensionMap: Record<string, string> = {
  'text/html': 'html',
  'text/xml': 'xml',
  'application/xml': 'xml',
  'application/atom+xml': 'xml',
  'application/rss+xml': 'xml',
  'application/yaml': 'yaml',
}

const determineExtension = (
  mimeType: string,
  userExtensionMap?: Record<string, string>
): string => {

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Check the appended underlying message — it names the real failure (network abort, body locked, etc.)
  2. Make page handlers return self-contained/robust Responses: fetch with retries or use resilient upstream calls, and never consume the body before returning it
  3. Return a fresh `new Response(...)` (string/Buffer) from handlers instead of piping remote streams
  4. Verify network access/DNS in the CI/build environment when pages fetch external APIs

Example fix

// before
app.get('/page', async (c) => {
  return fetch('https://api.example.com/data') // stream may fail during SSG read
})

// after
app.get('/page', async (c) => {
  const res = await fetch('https://api.example.com/data')
  const body = await res.text() // materialize before returning
  return c.html(render(body))
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function safeFetchPage(url: string): Promise<Response | null> {
  try {
    const r = await fetch(url)
    if (!r.ok) return null
    await r.arrayBuffer() // warm/validate body readability
    return r.clone()
  } catch { return null }
}

Try / catch

try { await toSSG(app, fs) } catch (e) { if (e instanceof Error && e.message.startsWith('Error processing response:')) { console.error(e.message); process.exit(1) } throw e }

Prevention

When it happens

Trigger: During `toSSG(app, fs, options)` a page handler returns a Response whose stream fails mid-read (upstream fetch died, body already consumed by other code), or arrayBuffer()/text() rejects on a non-cloneable/locked body. The underlying error message is appended.

Common situations: SSG pages that fetch remote content and the remote drops the connection at build time; handlers that consume response.body themselves before returning; returning exotic body types (ReadableStream from another runtime) to the SSG crawler; build environment with restricted network.

Related errors


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