honojs/hono · error · Error
This context has no ExecutionContext
Error message
This context has no ExecutionContext
What it means
Hono's Context.executionCtx getter throws when no ExecutionContext was captured for the current request. Hono stores the ctx argument from fetch(request, env, ctx) in a private field; if the handler chain never received one (non-workers runtimes, direct app.request() calls), the getter has nothing to return and throws.
Source
Thrown at src/context.ts:395
get event(): FetchEventLike {
if (this.#executionCtx && 'respondWith' in this.#executionCtx) {
return this.#executionCtx
} else {
throw Error('This context has no FetchEvent')
}
}
/**
* @see {@link https://hono.dev/docs/api/context#executionctx}
* The ExecutionContext associated with the current request.
*
* @throws Will throw an error if the context does not have an ExecutionContext.
*/
get executionCtx(): ExecutionContext {
if (this.#executionCtx) {
return this.#executionCtx as ExecutionContext
} else {
throw Error('This context has no ExecutionContext')
}
}
/**
* @see {@link https://hono.dev/docs/api/context#res}
* The Response object for the current request.
*/
get res(): Response {
return (this.#res ||= createResponseInstance(null, {
headers: (this.#preparedHeaders ??= new Headers()),
}))
}
/**
* Sets the Response object for the current request.
*
* @param _res - The Response object to set.
*/View on GitHub (pinned to e2740d5a1b)
Solutions
- Make waitUntil usage conditional: use c.executionCtx only when available, otherwise await the task or fire-and-forget
- In tests, pass a stub ExecutionContext as the third argument to app.request(req, env, fakeCtx)
- On Cloudflare Workers, ensure the ctx parameter is forwarded to Hono's fetch handler
- Consider a helper that wraps task execution with a fallback when executionCtx is missing
Example fix
// before
c.executionCtx.waitUntil(syncAnalytics()) // throws on Node.js
// after
const task = syncAnalytics()
if ('executionCtx' in c && c.executionCtx) {
// may still throw if absent; prefer explicit runtime check
}
try {
c.executionCtx.waitUntil(task)
} catch {
await task
} Defensive patterns
Strategy: try-catch
Type guard
const hasExecutionContext = (c: Context): boolean => {
try {
c.executionCtx
return true
} catch {
return false
}
} Try / catch
try {
c.executionCtx.waitUntil(task)
} catch {
// No ExecutionContext — run inline or fire-and-forget
void task.catch(() => {})
} Prevention
- Guard waitUntil calls behind a runtime capability check
- Use runtime-specific adapters that forward ctx
- In tests, pass a fake ExecutionContext with waitUntil/passThroughOnException to app.request
When it happens
Trigger: Calling c.executionCtx.waitUntil(...) (or passThroughOnException) in a handler running under @hono/node-server, denoServe, Bun.serve, AWS Lambda adapters that don't forward an execution context, or in tests invoked via app.request() without the third executionCtx argument.
Common situations: Using waitUntil in code meant to be runtime-agnostic; upgrading/migrating from Wrangler dev to local Node dev where ctx is absent; unit tests calling app.request(path, env) without an ExecutionContext.
Related errors
- This context has no FetchEvent
- Failed to upgrade WebSocket
- env has to include the 2nd argument of fetch.
- Context is not finalized. Did you forget to return a Respons
- Invalid JSX tag name: ${tag}
AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28).
Data as JSON: /api/errors/9aab035b8b2e01e1.
Report an issue: GitHub.