From 3026fe44b4a370c2f3b6d111f1b8c01b15d781d3 Mon Sep 17 00:00:00 2001 From: Akanksha Trehun Date: Sun, 20 Sep 2026 15:19:47 +0530 Subject: [PATCH] Guard against a None RpcError details in DaprWorkflowClient.get_workflow_state The async client already checks error.details() before searching it for 'no such instance exists'. The sync client does not, so any RpcError whose details() returns None, such as UNAVAILABLE when the sidecar is unreachable, crashes with a TypeError instead of surfacing the real error. Signed-off-by: Akanksha Trehun --- dapr/ext/workflow/dapr_workflow_client.py | 2 +- tests/ext/workflow/test_workflow_client.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dapr/ext/workflow/dapr_workflow_client.py b/dapr/ext/workflow/dapr_workflow_client.py index dca65c200..534b087ae 100644 --- a/dapr/ext/workflow/dapr_workflow_client.py +++ b/dapr/ext/workflow/dapr_workflow_client.py @@ -161,7 +161,7 @@ def get_workflow_state( state = self.__obj.get_orchestration_state(instance_id, fetch_payloads=fetch_payloads) return WorkflowState(state) if state else None except RpcError as error: - if 'no such instance exists' in error.details(): + if error.details() and 'no such instance exists' in error.details(): self._logger.warning(f'Workflow instance not found: {instance_id}') return None self._logger.error( diff --git a/tests/ext/workflow/test_workflow_client.py b/tests/ext/workflow/test_workflow_client.py index 257e72b35..deaad9883 100644 --- a/tests/ext/workflow/test_workflow_client.py +++ b/tests/ext/workflow/test_workflow_client.py @@ -70,6 +70,8 @@ def get_orchestration_state(self, instance_id, fetch_payloads): return self._inner_get_orchestration_state( instance_id, client.OrchestrationStatus.PENDING ) + elif wf_status == 'no-details': + raise SimulatedRpcError(code='UNAVAILABLE', details=None) else: raise SimulatedRpcError(code='UNKNOWN', details='unknown error') @@ -250,6 +252,10 @@ def test_client_functions(self): assert actual_get_result is None + wf_status = 'no-details' + with self.assertRaises(RpcError): + wfClient.get_workflow_state(instance_id=mock_instance_id, fetch_payloads=True) + wf_status = 'found' actual_get_result = wfClient.get_workflow_state( instance_id=mock_instance_id, fetch_payloads=True