Skip to content

fix: Add missing non-Task validation in resume() isFailed path#165

Open
YunchuWang wants to merge 1 commit intomainfrom
copilot-finds/bug/missing-non-task-validation-in-resume-failed-path
Open

fix: Add missing non-Task validation in resume() isFailed path#165
YunchuWang wants to merge 1 commit intomainfrom
copilot-finds/bug/missing-non-task-validation-in-resume-failed-path

Conversation

@YunchuWang
Copy link
Member

Summary

Add non-Task validation in the isFailed path of
esume(), making it consistent with the isComplete path.

Closes #161

Problem

In
esume(), the isComplete path correctly validates that the yielded value is a Task instance and throws a clear error. The isFailed path lacks this validation entirely - it silently returns when the yielded value is not a Task, leaving _previousTask pointing to the old failed task and causing confusing behavior on subsequent events.

Fix

Add hrow new Error('The orchestrator generator yielded a non-Task object') after the instanceof Task check in the isFailed path.

… path

When an orchestrator catches an exception from a failed task and yields
a non-Task value, the runtime silently falls through without reporting
an error. This leaves _previousTask pointing to the old failed task,
corrupting the generator state. On the next resume() call, the same
exception is thrown to the generator again in an unexpected location.

The isComplete path already validates this (line 184-186) and throws
a clear error: 'The orchestrator generator yielded a non-Task object'.
The isFailed path lacked this same validation.

This fix adds the same non-Task validation to the isFailed path,
ensuring consistent behavior and a clear error message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 11, 2026 18:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a generator state-corruption bug in the DurableTask JS orchestration runtime by enforcing Task-only yields when resuming after a failed task, aligning the isFailed resume path with the existing isComplete validation behavior (closes #161).

Changes:

  • Add non-Task yield validation in RuntimeOrchestrationContext.resume() when resuming via generator.throw(...) after task failure.
  • Add regression coverage for yielding a non-Task after catching a failure, plus a positive test for catching a failure and yielding a new Task.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/durabletask-js/src/worker/runtime-orchestration-context.ts Throws a clear error if a generator yields a non-Task after catching a failed task exception, preventing silent state corruption.
packages/durabletask-js/test/orchestration_executor.spec.ts Adds tests to verify orchestration fails with the expected error on non-Task yield after a caught failure, and succeeds when a new Task is yielded.

You can also share your feedback on Copilot code review. Take the survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[copilot-finds] Bug: Missing non-Task validation in resume() isFailed path causes silent generator state corruption

2 participants