diff --git a/CHANGELOG.md b/CHANGELOG.md index be3444177..5511b5715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ to include examples, links to docs, or any other relevant information. ### Fixed +- Nexus-context workflow/activity starts no longer set `on_conflict_options` when there are no links + or callbacks to attach. + ### Security ## [1.32.0] - 2026-08-24 diff --git a/temporalio/nexus/_operation_context.py b/temporalio/nexus/_operation_context.py index c44088f21..327e9c51b 100644 --- a/temporalio/nexus/_operation_context.py +++ b/temporalio/nexus/_operation_context.py @@ -821,19 +821,17 @@ def _apply_nexus_context_to_start_workflow_request( # pyright: ignore[reportUnu This is a no-op outside a Nexus operation context. Within one, it attaches inbound links and configures conflict handling to preserve Nexus metadata. The Nexus request ID and completion callbacks are added only when the - workflow is backing the Nexus operation. + workflow is backing the Nexus operation. on_conflict_options is populated + only when there are links or callbacks to attach. """ nexus_ctx = _try_start_operation_context() if nexus_ctx is not None: - req.on_conflict_options.attach_request_id = True - req.on_conflict_options.attach_completion_callbacks = True - req.on_conflict_options.attach_links = True - request_links = nexus_ctx._get_request_links() # Links are duplicated on request for compatibility with older server versions. req.links.extend(request_links) + callbacks: list[NexusCallback] = [] if _in_nexus_backing_start_context(): req.request_id = nexus_ctx.nexus_context.request_id callbacks = nexus_ctx._get_callbacks( @@ -854,6 +852,11 @@ def _apply_nexus_context_to_start_workflow_request( # pyright: ignore[reportUnu for callback in callbacks ) + if request_links or callbacks: + req.on_conflict_options.attach_request_id = True + req.on_conflict_options.attach_completion_callbacks = True + req.on_conflict_options.attach_links = True + def _apply_start_workflow_response_to_nexus_context( # pyright: ignore[reportUnusedFunction] workflow_handle: temporalio.client.WorkflowHandle[Any, Any], @@ -872,16 +875,15 @@ def _apply_nexus_context_to_start_activity_request( # pyright: ignore[reportUnu the Nexus request ID and configures conflict handling to preserve the Nexus metadata. Inbound links are attached to the completion callback when the activity backs the operation and to the request otherwise. + on_conflict_options is populated only when there are links or callbacks to + attach. """ nexus_ctx = _try_start_operation_context() if nexus_ctx is not None: - req.on_conflict_options.attach_request_id = True - req.on_conflict_options.attach_completion_callbacks = True - req.on_conflict_options.attach_links = True - req.request_id = nexus_ctx.nexus_context.request_id request_links = nexus_ctx._get_request_links() + callbacks: list[NexusCallback] = [] if _in_nexus_backing_start_context(): callbacks = nexus_ctx._get_callbacks( OperationToken( @@ -903,6 +905,11 @@ def _apply_nexus_context_to_start_activity_request( # pyright: ignore[reportUnu else: req.links.extend(request_links) + if request_links or callbacks: + req.on_conflict_options.attach_request_id = True + req.on_conflict_options.attach_completion_callbacks = True + req.on_conflict_options.attach_links = True + def _apply_start_activity_response_to_nexus_context( # pyright: ignore[reportUnusedFunction] activity_id: str,