Skip to content

workflow: seed the guid namespace from history when the request has n… - #1880

Merged
WhitWaldo merged 7 commits into
dapr:masterfrom
JoshVanL:pr/workflow-executionid-history-fallback
Aug 14, 2026
Merged

workflow: seed the guid namespace from history when the request has n…#1880
WhitWaldo merged 7 commits into
dapr:masterfrom
JoshVanL:pr/workflow-executionid-history-fallback

Conversation

@JoshVanL

Copy link
Copy Markdown
Contributor

…o execution ID

The worker seeds the orchestration context's deterministic guid namespace from WorkflowRequest.ExecutionId, falling back to the instance ID when it is unset. Sidecars built on durabletask-go never set it, so the fallback always engaged, and TaskExecutionId derivation (seeded by that namespace) produced identical values across different executions of the same instance ID.

That collision is not cosmetic: when a completed instance is recreated with the same instance ID (create-if-completed semantics) and the new execution schedules the same task ID and activity name, the runtime's activity de-duplication sees the same TaskExecutionId as the previous execution's completed activity, treats the new scheduling as a redelivery, and acks it without dispatching. No TaskCompleted is ever produced and the recreated workflow is stuck in Running forever, along with any parent awaiting it.

Fix: when the request carries no execution ID, recover the runtime-minted execution ID persisted in the history's ExecutionStartedEvent (workflowInstance.executionId). It is stable across replays of one execution, distinct per execution of a recreated instance, and present in histories written by durabletask-go backends. When neither source provides one, behavior is unchanged.

…o execution ID

The worker seeds the orchestration context's deterministic guid
namespace from WorkflowRequest.ExecutionId, falling back to the instance
ID when it is unset. Sidecars built on durabletask-go never set it, so
the fallback always engaged, and TaskExecutionId derivation (seeded by
that namespace) produced identical values across different executions of
the same instance ID.

That collision is not cosmetic: when a completed instance is recreated
with the same instance ID (create-if-completed semantics) and the new
execution schedules the same task ID and activity name, the runtime's
activity de-duplication sees the same TaskExecutionId as the previous
execution's completed activity, treats the new scheduling as a
redelivery, and acks it without dispatching. No TaskCompleted is ever
produced and the recreated workflow is stuck in Running forever, along
with any parent awaiting it.

Fix: when the request carries no execution ID, recover the
runtime-minted execution ID persisted in the history's
ExecutionStartedEvent (workflowInstance.executionId). It is stable
across replays of one execution, distinct per execution of a recreated
instance, and present in histories written by durabletask-go backends.
When neither source provides one, behavior is unchanged.

Signed-off-by: joshvanl <me@joshvanl.dev>
@JoshVanL
JoshVanL requested a balanced review from Copilot August 13, 2026 14:02
@JoshVanL
JoshVanL requested review from a team as code owners August 13, 2026 14:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Seeds deterministic workflow GUID generation from the execution ID stored in history when the request omits it, preventing task execution ID collisions across recreated workflow executions.

Changes:

  • Recovers the execution ID from the latest ExecutionStartedEvent.
  • Passes the recovered ID into WorkflowOrchestrationContext.
  • Adds coverage for distinct IDs across executions and stable IDs during replay.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Dapr.Workflow/Worker/WorkflowWorker.cs Recovers and applies the persisted execution ID.
test/Dapr.Workflow.Test/Worker/WorkflowWorkerTests.cs Tests task execution ID uniqueness and replay stability.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Dapr.Workflow/Worker/WorkflowWorker.cs Outdated
Signed-off-by: joshvanl <me@joshvanl.dev>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment on lines +109 to +111
var taskExecutionSeed = !string.IsNullOrWhiteSpace(executionId) ? executionId
: !string.IsNullOrWhiteSpace(historyExecutionId) ? historyExecutionId
: instanceId;

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.

@JoshVanL This seems reasonable - could you make this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @WhitWaldo, done!

@WhitWaldo WhitWaldo added this to the v1.18.x - SDK Patches milestone Aug 14, 2026
@WhitWaldo WhitWaldo added area/workflow kind/bug Something isn't working labels Aug 14, 2026

@WhitWaldo WhitWaldo 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.

Looks good to me - thank you!

@WhitWaldo
WhitWaldo merged commit 3392648 into dapr:master Aug 14, 2026
947 of 955 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/workflow kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants