@@ -1209,9 +1209,58 @@ async def test_workflow_cancel_child_started(client: Client, use_execute: bool):
12091209 assert isinstance (err .value .cause .cause , CancelledError )
12101210
12111211
1212- @pytest .mark .skip (reason = "unable to easily prevent child start currently" )
1213- async def test_workflow_cancel_child_unstarted (_client : Client ):
1214- raise NotImplementedError
1212+ @workflow .defn
1213+ class CancelDuringChildStartWorkflow :
1214+ def __init__ (self ) -> None :
1215+ self ._proceed = False
1216+
1217+ @workflow .signal
1218+ def proceed (self ) -> None :
1219+ self ._proceed = True
1220+
1221+ @workflow .run
1222+ async def run (self ) -> None :
1223+ await workflow .wait_condition (lambda : self ._proceed )
1224+ # Start a child on a task queue with no worker. The child's first WFT
1225+ # never starts, so _start_fut remains unresolved and the start loop
1226+ # blocks forever.
1227+ await workflow .start_child_workflow (
1228+ LongSleepWorkflow .run ,
1229+ id = f"{ workflow .info ().workflow_id } _child" ,
1230+ task_queue = "nonexistent-task-queue-no-worker-abc123" ,
1231+ )
1232+ await workflow .sleep (1000 )
1233+
1234+
1235+ async def test_workflow_cancel_child_unstarted (client : Client ):
1236+ # Regression test for https://github.com/temporalio/sdk-python/issues/1445
1237+ #
1238+ # When cancellation arrived while the parent was waiting for a child
1239+ # workflow to start, the CancelledError was caught in the start loop
1240+ # to send a cancel command to the child — but was not re-raised.
1241+ # Because _start_fut never resolves (child on a queue with no worker),
1242+ # the loop would keep waiting forever, hanging the parent workflow.
1243+ #
1244+ # The fix: re-raise only when self._cancel_requested is True, which
1245+ # distinguishes Temporal workflow cancellation from other CancelledError
1246+ # sources such as asyncio.wait_for timeouts.
1247+ async with new_worker (
1248+ client ,
1249+ CancelDuringChildStartWorkflow ,
1250+ # Deliberately not registering LongSleepWorkflow and not starting
1251+ # a worker on the child's task queue.
1252+ ) as worker :
1253+ handle = await client .start_workflow (
1254+ CancelDuringChildStartWorkflow .run ,
1255+ id = f"workflow-{ uuid .uuid4 ()} " ,
1256+ task_queue = worker .task_queue ,
1257+ execution_timeout = timedelta (seconds = 30 ),
1258+ )
1259+ await handle .signal (CancelDuringChildStartWorkflow .proceed )
1260+ await handle .cancel ()
1261+ with pytest .raises (WorkflowFailureError ) as err :
1262+ await handle .result ()
1263+ assert isinstance (err .value .cause , CancelledError )
12151264
12161265
12171266@workflow .defn
0 commit comments