You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Human-in-the-loop response is accepted after the task has stopped waiting #75531
PATCH .../taskInstances/{task_id}/{map_index}/hitlDetails records the response whenever the
request has none yet. It resumes the task only if the task is still awaiting_input or deferred.
When response_timeout passes with no defaults, the scheduler fails the task without writing a
response. A response submitted afterwards is therefore stored and answered with 200, and the UI shows
"response successful", but nothing resumes. The task stays failed, and the history shows a decision
that never took effect.
Reproduce:
ApprovalOperator(subject="...", response_timeout=timedelta(seconds=20)), with no defaults
and retries=0.
Open its Required Actions page, then wait for the task to fail on timeout without reloading.
Click Approve in the page that is still open. The UI reports success and the history records the
approval. The task and its downstream tasks remain failed or upstream_failed.
A freshly opened page disables the buttons. Only a page loaded before the timeout lets this through,
and the API accepts it from any client.
What you think should happen instead?
A response to a request whose task is no longer waiting for it is refused, for example with 409, with
a message that the request expired or the task stopped waiting. It should not be recorded as a
decision.
Anything else?
The task failing and not reviving is correct; the problem is the success feedback and the stored
answer.
@estella00911 if you're looking into this (or anyone later) - the write and the resume are not gated by the same check. The resume is gated on the task instance state whereas the write is not. The fix would be to decide once, before anything is stored, and return 409 when the task is not waiting anymore.
Activity
estella00911 commentedon Oct 25, 2026
I am looking into this issue.
amoghrajesh commentedon Oct 26, 2026
@estella00911 if you're looking into this (or anyone later) - the write and the resume are not gated by the same check. The resume is gated on the task instance state whereas the write is not. The fix would be to decide once, before anything is stored, and return 409 when the task is not waiting anymore.
estella00911 commentedon Oct 26, 2026
Thanks @amoghrajesh for the clarification!
I tried a similar state check that only allows
AWAITING_INPUTandDEFERRED, but I noticed two possibleRUNNINGscenarios:RUNNING→ HITL request created → User responds before parking →SCHEDULEDAWAITING_INPUT→ Timeout →SCHEDULED→RUNNING(handling timeout event) →FAILEDI found that
TIAwaitingInputStatePayloadseems to handle early responses.Should we also consider the
RUNNINGstate when deciding whether to return 409?I reproduced the original issue, but haven't reproduced these
RUNNINGscenarios myself yet.