DEV Community

HaoPeng Zhang
HaoPeng Zhang

Posted on

The Workflow That Waited for a Human Who Never Came: Timeouts for Approval Steps in n8n

This is part of my build-in-public series on running LLM workflows in n8n in production. Everything here is from real templates I sell and support — the mistakes are mine, the fixes are tested.

The queue was full. Nothing had failed

A workflow of mine drafted replies to customer messages, then parked each one in a review queue for a human to approve before sending. It ran clean for weeks. Then one Monday the queue held forty unapproved drafts, the oldest three days old, and a customer asked why nobody had answered her.

Nothing had failed. No node was red, no execution had errored. The workflow had done exactly what it was built to do: wait for a human. The human was on holiday, and nobody had told the workflow.

This is the failure mode that hides inside every human-in-the-loop step. An approval gate is not a pause button. It is a dependency on a person, and people go on holiday, get sick, and get busy. A workflow that waits forever for a human is a workflow with an unbounded timeout, and an unbounded timeout is just a slow outage wearing a green status.

Every human gate needs three things

The fix is not to remove the human. The human is there for a reason — some messages should not go out unchecked. The fix is to decide, before the workflow ships, what happens when the human does not show up.

First, a timeout. Every approval step gets a deadline, and the deadline is a business decision, not a technical one. A customer reply might get four hours. An internal report might get one business day. The number matters less than the fact that one exists and is written down, because "wait until someone approves" is not a deadline, it is an abdication.

Second, an escalation. When the timeout hits, the item does not sit there. It moves: to a second approver, to a shared channel, to whoever is on call. The escalation itself is a workflow step, not a hope that someone will notice the queue. In my case the escalation is a message that names the item, its age, and the action needed — not "there are items pending," which everyone ignores, but "this draft for this customer has waited 4 hours, approve or reject here."

Third, a default action. If nobody approves even after escalation, the workflow must still do something, and that something must be chosen in advance. For customer replies, my default is to send a holding message — "we received this, a human will follow up" — rather than silence. For internal drafts, the default is to park the item in a stale list with an alert, not to send it. The rule is simple: the safe default depends on the cost of silence versus the cost of a wrong send, and it is decided when you are calm, not when the queue is already full.

The stale queue is a metric, not a feeling

Once the timeouts exist, the review queue stops being something you check when you remember and becomes something you measure. I track two numbers: the oldest unapproved item's age, and the count of items past their deadline. Either number crossing its threshold pages me the same way a failed execution does, because a queue full of stale approvals is a failure, even though no node turned red.

The principle is simple: automation that waits on a human inherits that human's availability. If you do not bound the wait, escalate the stall, and define the default, you have not automated the process — you have automated the first half of it and left the second half to chance.


I'm building AI Automation Lab — production-ready n8n workflow templates. The free AI Hook Generator shows how I structure real workflows; my open-source templates live at github.com/zhp910318/n8n-ai-automation-lab.

Top comments (0)