fix(workflow): forward parent pointer when spawning a child with discard:true#6241
Merged
tim-smart merged 2 commits intoMay 19, 2026
Merged
Conversation
…ard:true The discard fast-path in WorkflowEngine.execute omitted the `parent` option when delegating to the engine, so ClusterWorkflowEngine never wrote `"~@effect/workflow/parent"` into the child's persisted payload. This broke causality tracking for fire-and-forget fan-outs — a common pattern when one workflow spawns many children and doesn't need to await them. Discarded children now carry the same parent pointer non-discarded children already did, restoring observability without changing fire-and-forget semantics. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: fdd957b The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
tim-smart
reviewed
May 19, 2026
Co-authored-by: Tim <hello@timsmart.co>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Workflow.execute(payload, { discard: true })takes a fast path insideWorkflowEngine.executethat omits theparentoption when delegating to the underlying engine. As a result,ClusterWorkflowEnginenever writes"~@effect/workflow/parent"into the child's persistedcluster_messages.payloadrow.The non-discard branch a few lines below DOES forward
parent, so the discard path looks like an oversight —parentcarries two concerns and only one of them (interrupt linkage) is moot for discarded children. The other (the persisted causality breadcrumb) is still load-bearing for any observability surface that wants to reconstruct a parent/child workflow tree from message storage.Before this fix:
After:
The fix is one line. The
parentoption is already typed as optional on the engine'sexecutesignature, so no other surfaces change.Why this matters
The dominant fan-out shape in
@effect/clusterworkflows —Effect.forEach(items, (item) => ChildWorkflow.execute(item, { discard: true }))— was leaving every child's payload without a parent pointer. Tools that read cluster_messages to reconstruct a Temporal-like workflow tree end up with orphaned children and no way to link them back to their parent, except by falling back to OTel trace_id grouping (which is lossy and ambiguous for nested fan-outs).Test
Added a regression test in
packages/cluster/test/ClusterWorkflowEngine.test.tsthat spawns a child withdiscard: trueand asserts the persisted child run-envelope carries"~@effect/workflow/parent"pointing back at the parent's actualexecutionId.Changeset
@effect/workflow: patch.Test plan
pnpm vitest runinpackages/cluster— all 9 tests pass, including the new one.pnpm vitest runinpackages/workflow— all 6 tests pass.tsc -bclean across both packages.eslintclean on the touched files.🤖 Generated with Claude Code