Skip to content

fix: propagate exceptions from immediately-failed tasks in resume() loop#329

Open
YunchuWang wants to merge 1 commit into
mainfrom
copilot-finds/bug/resume-loop-swallows-failed-task-exception
Open

fix: propagate exceptions from immediately-failed tasks in resume() loop#329
YunchuWang wants to merge 1 commit into
mainfrom
copilot-finds/bug/resume-loop-swallows-failed-task-exception

Conversation

@YunchuWang

Copy link
Copy Markdown
Member

Fixes #206.

The resume() while-loop silently swallowed exceptions thrown by immediately-failed tasks. This propagates those exceptions instead of dropping them.


Opens the existing fix branch copilot-finds/bug/resume-loop-swallows-failed-task-exception as a PR (automated triage of active [copilot-finds] issues that had a ready fix branch but no open PR).

…y-failed tasks

When the resume() method's isComplete while-loop encountered a task that
was already failed (e.g., a WhenAllTask with a pre-failed child), it
continued looping and called generator.next(undefined) instead of
throwing the exception into the generator via generator.throw(). This
caused failed task exceptions to be silently lost.

The fix adds a check for isFailed inside the while-loop. When an
immediately-failed task is detected, it breaks out and delegates to the
isFailed handling branch via a recursive resume() call.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 16:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 correctness bug in the orchestration replay/resume loop: when an orchestrator yields a task that is already complete but failed (e.g., whenAll([...]) with a pre-failed child), the runtime now correctly throws the task exception into the generator instead of resuming with an undefined result and silently losing the error. This aligns with the SDK’s generator-based replay model, where failed yielded tasks must surface as exceptions to deterministic orchestrator code.

Changes:

  • Update RuntimeOrchestrationContext.resume() to detect immediately-failed tasks inside the “immediately-complete” loop and route them through the existing failure/generator.throw() path.
  • Add regression coverage for the pre-failed-child whenAll scenario, validating both caught-exception and uncaught-exception outcomes.

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 Ensures immediately-failed yielded tasks propagate via generator.throw() instead of being treated like successful completions in the resume loop.
packages/durabletask-js/test/orchestration_executor.spec.ts Adds regression tests that reproduce the original “swallowed exception” scenario and assert correct completion vs failure behavior.

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: resume() while-loop silently swallows exceptions from immediately-failed tasks

3 participants