Use runtime helpers without passing the event through every function
Use explicit event parameters at handler boundaries, then use , , , , , , and inside helper code that runs during the same request or job.
The everyday rule is simple: accept the event in the handler, pass explicit data where it is clearer, and use runtime helpers when nested helper code needs the active request, env, context, event, or request-scoped .
- Main rule
- Event at the boundary, helpers inside the same handler trail
- Main helpers
- , , , , , , and
- Stored shape
- , , , , and while a handler is active
- Mutable lane
- /
- Failure mode
- Strict runtime helpers throw outside an active handler trail
Pick the helper that matches where your code is running
If or works in one helper and fails in another, first check whether that code still runs during the active request, job, or Durable Object call.
Use per-surface getters when the helper needs the current event, use or when a helper only needs active bindings or execution context, and use for request-scoped data shared across middleware and helper calls.
| Helper family | Examples | Use it for |
|---|---|---|
| Per-surface getters | , , , , | Return the current rich event after verifying the active surface type; returns instead of throwing. |
| Generic context getter | Returns the active stored context shape when one exists and throws when code is running outside an active handler trail. | |
| Readonly runtime proxies | , , | Read the active environment bindings, execution context, or current event without threading parameters through every helper. |
| Mutable runtime proxy | Reads and writes the per-request or per-job mutable storage object attached to the active context. |
A practical reading guide
If the question in your head is “when can I safely call or read without passing the event around?”, the rest of this page is answering exactly that.
Start with event-first handlers and let helpers discover the active event later
Event-first handlers keep runtime state explicit at the boundary and still let nested helpers recover the current event later when plumbing it through every function call would be pure ceremony. That is the everyday job for helpers like and .
In normal application code you should not need to establish runtime context manually. Devflare already does that for generated worker entrypoints, middleware, route dispatch, Durable Object wrappers, the dev server, and the built-in test helpers.
Use the explicit event at the boundary and a getter inside the helper
This keeps the handler honest while still letting helper code read the active request and shared locals later in the same call trail.
Open internals only when helper setup is the problem
The normal runtime-context page should help you write application code. Open the internals page only when you are changing runtime infrastructure, debugging helper setup, or checking how Devflare creates the active context.
Getters and proxies are just different ways of reading the same store
Pass the event explicitly at the top of the stack. Reach for getters or proxies only when helper code is still running in the same handler trail and threading that event downward would make the code noisier than the value it adds.
This is also why strict runtime helpers throwing outside context is healthy: it stops top-level module code and random utility calls from pretending they are running inside a request when they are not.
| API | What it reads | Failure behavior | Mutation |
|---|---|---|---|
| Handler parameters | The explicit event object Devflare passes to the handler boundary. | No lookup needed at the boundary. | is mutable. |
| Per-surface getters like | The stored after Devflare verifies the active surface type. | Throws , while returns . | Readonly event view. |
| The full active object for the current handler trail. | Throws outside an active handler trail. | Use this mostly for debugging or advanced infrastructure helpers. | |
| , , proxies | through readonly proxy wrappers. | Property access throws outside an active handler trail. | Readonly. |
| proxy | through the mutable context proxy. | Property access throws outside an active handler trail. | Mutable and shared with . |
A simple rule
Use explicit handler parameters first, getters second, proxies third, and mutable only for data that truly belongs to the current request or job.
Runtime helpers cover more than fetch
Worker surfaces expose as the current . Durable Object surfaces expose as the current , and Devflare also aliases that same value as for clarity.
For fetch and Durable Object fetch, Devflare augments the actual instance. For queue, scheduled, email, tail, and Durable Object WebSocket surfaces, it augments the native carrier object instead of replacing it with a fantasy wrapper.
Three general-purpose utilities round out the API: checks whether a context is active, returns the current event regardless of surface type, and does the same but returns outside a context.
| Surface | Event shape | Getter |
|---|---|---|
| HTTP worker | ||
| Queue consumer | ||
| Scheduled handler | ||
| Inbound email | ||
| Tail handler | ||
| Durable Object fetch | ||
| Durable Object alarm | ||
| Durable Object WebSocket message / close / error | Dedicated WebSocket event types | , , |
| Any Durable Object surface |
is the mutable storage lane, and it is isolated per context
Use for auth state, derived request data, request ids, or other values that belong to the current request or job and should be shared across middleware or helper layers.
Within one handler trail, and point at the same underlying object. Across requests and jobs, each context gets a fresh locals object so state does not bleed between invocations.
Mutate , not the readonly proxies
, , and are readonly runtime views. If you need shared mutable state, put it on instead of trying to assign back into the underlying context objects.
Write to `event.locals`, read from `locals` later in the same trail
Context is not available everywhere, and that is intentional
- Module top-level code runs at cold start, not inside a request or job, so strict runtime helpers are unavailable there.
- Callbacks that run after the handler trail ends should take explicit inputs instead of assuming context is still alive.
- Timer callbacks like and are outside the normal Devflare-managed handler trail.
- Per-surface getters and throw , while proxy property access such as or throws naming the missing property.
- If you are unsure whether the matching surface is active, prefer accessors such as over catching thrown errors.
- If runtime context access fails unexpectedly while bypassing Devflare-generated config or harnesses, open the runtime context internals page and verify the Worker still includes the compatibility flags Devflare normally adds for you.
The fix is usually simpler than the error feels
Move the context access inside the handler, middleware, or helper that is called from that handler trail. If there is no active trail, take explicit inputs instead of hoping context exists.
Previous
Runtime & deploy settings
Use config for account context, compatibility posture, assets, deployment routes, WebSocket proxy rules, migrations, observability, limits, and preview cron behavior instead of rediscovering those settings in scripts later.
Next
Runtime internals
This page keeps the AsyncLocalStorage mechanics out of the normal usage guide while preserving them for maintainers and advanced debugging.