Lifecycle hooks provide a mechanism to execute custom code at specific points during a task's execution lifecycle. They enable pre-execution setup, post-execution cleanup, success/failure handling, and cancellation logic without cluttering the main task function. Lifecycle hooks can be defined at the task level (for individual tasks) or globally (for all tasks in the project).
For information about task definition and execution, see Task Definition API. For information about error handling and retry configuration, see Retry and Error Handling.
The following diagram illustrates when each lifecycle hook fires during task execution:
Sources: packages/trigger-sdk/CHANGELOG.md145-180 packages/core/CHANGELOG.md409
The onStartAttempt hook fires before the run function executes on every attempt, including retries. This replaces the deprecated onStart hook which only fired before the first attempt.
Use cases:
Signature:
Access to:
payload: The task payloadctx: Full task context including ctx.run.attempt.numberExample usage pattern:
Sources: packages/trigger-sdk/CHANGELOG.md147-180 packages/core/CHANGELOG.md145-181
The onSuccess hook fires after the task completes successfully, with access to the task's output.
Use cases:
Signature:
Access to:
payload: The task payloadoutput: The value returned by the run functionctx: Full task contextSources: packages/trigger-sdk/CHANGELOG.md145-146 packages/core/CHANGELOG.md409
The onFailure hook fires after each failed attempt, including intermediate failures that will be retried.
Use cases:
Signature:
Access to:
payload: The task payloaderror: The error that caused the failurectx: Full task context including ctx.run.attempt.numberImportant: This hook fires after every failed attempt, not just the final failure. Check ctx.run.attempt.number against retry configuration to determine if this is the last attempt.
Sources: packages/trigger-sdk/CHANGELOG.md145-146 packages/core/CHANGELOG.md409
The onCancel hook fires when a run is cancelled, either by a user action or by the system.
Use cases:
Signature:
Access to:
payload: The task payloadctx: Full task contextSources: packages/trigger-sdk/CHANGELOG.md401 packages/core/CHANGELOG.md401
The onComplete hook fires at the end of the run lifecycle, regardless of outcome (success, failure, or cancellation). It always fires after onSuccess, onFailure, or onCancel.
Use cases:
Signature:
Access to:
payload: The task payloadctx: Full task context, including final statusExecution guarantee: onComplete is guaranteed to fire once per run, making it ideal for cleanup logic that must always execute.
Sources: packages/trigger-sdk/CHANGELOG.md145-146 packages/core/CHANGELOG.md409
Hooks can be defined directly on individual task definitions:
Sources: packages/trigger-sdk/CHANGELOG.md150-159
Global hooks apply to all tasks in the project and are registered using the tasks namespace:
Hook precedence: Both global and task-level hooks execute. Task-level hooks do not override global hooks; they run in addition to them.
Access to task: Global hooks receive a task parameter identifying which task is executing.
Sources: packages/trigger-sdk/CHANGELOG.md160-167
Execution order:
Sources: packages/trigger-sdk/CHANGELOG.md145-180
Lifecycle hooks have isolated error handling: errors thrown in hooks do not fail the run or attempt.
| Hook Error Location | Impact on Run | Impact on Attempt | Logged |
|---|---|---|---|
onStartAttempt | No failure | No failure | Yes |
onSuccess | No failure | No failure | Yes |
onFailure | No failure | No failure | Yes |
onCancel | No failure | No failure | Yes |
onComplete | No failure | No failure | Yes |
Rationale: Hooks are intended for side effects (logging, notifications, cleanup). Hook failures should not prevent the task from completing or reporting its actual outcome.
Error visibility: Hook errors are logged to the run's trace but do not change the run's status or trigger retries.
Best practices:
Sources: packages/trigger-sdk/CHANGELOG.md145-146
The onStart hook has been deprecated in favor of onStartAttempt.
| Issue | Description |
|---|---|
| Misleading name | onStart implied it ran at task start, but it only ran before the first attempt |
| Retry confusion | Resources initialized in onStart were not re-initialized on retries |
| Inconsistent behavior | Tasks requiring per-attempt setup had to handle this in the run function |
Before (deprecated onStart):
After (using onStartAttempt):
Key difference: onStartAttempt fires before every attempt, not just the first one.
Backwards compatibility: The onStart hook still works but will be removed in a future version. Update to onStartAttempt to future-proof your code.
Sources: packages/trigger-sdk/CHANGELOG.md147-149 packages/core/CHANGELOG.md145-181
The SDK exports TypeScript types for defining custom hook functions:
Available types:
AnyOnStartAttemptHookFunction - Type for onStartAttempt hooksSources: packages/trigger-sdk/CHANGELOG.md74
Execute logic only on the first attempt using onStartAttempt:
Sources: packages/trigger-sdk/CHANGELOG.md169-180
Use onComplete for guaranteed cleanup:
Use onFailure and onSuccess for outcome-specific notifications:
| Hook | Fires When | Frequency | Access to Output | Access to Error |
|---|---|---|---|---|
onStartAttempt | Before each attempt | Once per attempt | No | No |
onSuccess | After successful completion | Once per run | Yes | No |
onFailure | After failed attempt | Once per failed attempt | No | Yes |
onCancel | When cancelled | Once per run | No | No |
onComplete | After final outcome | Once per run | No | No |
Key guarantees:
onComplete always fires exactly once per runonStartAttempt fires before every attemptSources: packages/trigger-sdk/CHANGELOG.md145-180 packages/core/CHANGELOG.md409 packages/core/CHANGELOG.md145-181
Refresh this wiki