HIL Timeout — Overview
What happens when a HIL actor doesn't respond in time. Three configurable outcomes — escalate, auto-decide, or fail — ensure your workflow is never permanently blocked.
Why Timeouts Matter
Without timeouts, a HIL task waiting for a response can block a workflow indefinitely. An approver goes on leave. A form submission is forgotten. An email lands in spam. Timeouts are the safety mechanism that ensures workflows progress regardless of actor availability.
Three Timeout Outcomes
Escalate
Reassign the task to a senior actor (escalationActorId). The escalation actor gets a fresh deadline. Use for tasks that need human judgment but can be handled by a backup.
Auto-Decide
Engine injects a synthetic decision (AutoApprove or AutoReject). The workflow continues on the corresponding output port. Use when a default outcome is acceptable.
Fail
Engine throws TimeoutError — the workflow fails. Use when there is no acceptable fallback and the timeout represents a critical process failure.
Timeout Detection Architecture
| Component | Responsibility |
|---|---|
HILTimeoutJob | Background job (Hangfire/Quartz) that scans Process_SuspendedExecutions for rows where ExpiresAt < UtcNow and Status = Pending |
HILEscalationService | Resolves escalation actor, creates new HIL task, resets ExpiresAt |
HILAutoDecisionService | Injects synthetic decision, calls HILResumeService.ContinueAsync() |
Timeout Job Schedule
The timeout job runs on a configurable cron schedule — default every 2 minutes. Configure in appsettings.json:
"HILTimeout": {
"JobCronSchedule": "*/2 * * * *", // every 2 minutes
"BatchSize": 100 // process up to 100 expired tasks per run
}