Overview
errorcore tracks state per incident, not as a process-wide telemetry stream. That incident model is what lets the SDK combine a thrown error with the exact request, local values, and IO that belonged to the same failure path.
State buckets
Each incident package contains these distinct sections:
- Error metadata: type, message, stack trace, cause chain, and any custom properties on the error object.
- Request context: method, URL, headers, request ID, and optionally the request body. Present when the error occurred inside a middleware scope or
withContextcall. - Local variables: the values of variables in the call frames at the throw site. Requires
captureLocalVariables: true. - Ordered IO: the sequence of HTTP calls, database queries, DNS lookups, and other IO that happened during the request, with timing data.
- State reads: property accesses on objects registered with
trackState, showing what your code read before it failed. - Concurrent requests: a summary of other in-flight requests at the time of capture, useful for diagnosing resource contention.
- Process metadata: Node.js version, platform, PID, memory usage, event loop lag, and uptime.
How context is scoped
errorcore uses AsyncLocalStorage to scope state to the request that produced the error. IO events, state reads, and local variables are all grouped by request context automatically. If two requests are in flight and one fails, only the IO and state from the failing request is included.
For code paths outside a request (timers, queue consumers, startup logic), the SDK falls back to the ambient IO buffer, which stores recent events across all contexts.
Completeness
Every package includes a completeness object that reports what was and was not captured. If local variables were unavailable, or the IO buffer overflowed, or PII scrubbing ran, the completeness record says so. This lets you distinguish "nothing happened" from "something happened but was excluded by policy."