Setup
1. Create a hook file
Create a file that registers your handler. ImportonError from @outputai/core/hooks.
2. Register the file in package.json
List your hook file(s) underoutputai.hookFiles. Paths are relative to the package root. The worker loads these files at startup.
"hookFiles": ["./src/error_hooks.js", "./src/other_hooks.js"].
The three sources
Errors are emitted from three origins. Every payload includeseventId, eventDate, source, and error. Activity- and workflow-scoped errors also include Temporal execution details.
| Source | When it fires | Fields besides eventId, eventDate, source, and error |
|---|---|---|
activity | A step or evaluator fails (after retries are exhausted). | activityInfo, workflowDetails, outputActivityKind |
workflow | The workflow function itself throws (e.g. uncaught step error or logic error). | workflowDetails |
runtime | An error outside workflow/activity scope (e.g. in the worker/runtime). | — |
- Activity —
eventId,eventDate,source: 'activity',activityInfo,workflowDetails,outputActivityKind,error. - Workflow —
eventId,eventDate,source: 'workflow',workflowDetails,error(no activity fields). - Runtime —
eventId,eventDate,source: 'runtime', anderroronly.
activityInfo is Temporal’s Activity execution info object; see Temporal’s activity.Info reference. workflowDetails is Output’s serializable subset of Temporal’s workflow.WorkflowInfo, with fields such as workflowId, runId, workflowType, parent, and root.
outputActivityKind identifies the Output activity type. Possible values are step, evaluator, and internal_step.
eventId is a UUID v4 stamped per emit — use it as a stable idempotency key when forwarding errors to external systems (Sentry, PagerDuty, your own incident pipeline). eventDate is the millisecond epoch timestamp for when the event was emitted. Use source to branch in one handler, or ignore payload fields that are undefined for that source.
Handler safety: no throws
Your handler is wrapped in a try/catch. If the handler throws or rejects, the framework catches it, logs it (e.g.onError hook error with the error), and does not rethrow. Execution of the workflow and worker continues. You can focus on side effects (logging, metrics, alerts) without worrying about breaking the run.