From 715d03367709d5c2394dca8a712c3f7a9b9a838b Mon Sep 17 00:00:00 2001 From: Aniruddha Adak Date: Tue, 21 Apr 2026 15:22:58 +0530 Subject: [PATCH] fix(permissions): handle None response from ACP request_permission --- acp_adapter/permissions.py | 3 +++ tests/acp/test_permissions.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/acp_adapter/permissions.py b/acp_adapter/permissions.py index 68f61e340ab..c2e1a598269 100644 --- a/acp_adapter/permissions.py +++ b/acp_adapter/permissions.py @@ -63,6 +63,9 @@ def _callback(command: str, description: str) -> str: logger.warning("Permission request timed out or failed: %s", exc) return "deny" + if response is None: + return "deny" + outcome = response.outcome if isinstance(outcome, AllowedOutcome): option_id = outcome.option_id diff --git a/tests/acp/test_permissions.py b/tests/acp/test_permissions.py index de83ebeffd7..57e2bd4e5b9 100644 --- a/tests/acp/test_permissions.py +++ b/tests/acp/test_permissions.py @@ -73,3 +73,17 @@ def test_approval_timeout_returns_deny(self): result = cb("rm -rf /", "dangerous") assert result == "deny" + + def test_approval_none_response_returns_deny(self): + """When request_permission resolves to None, the callback should return 'deny'.""" + loop = MagicMock(spec=asyncio.AbstractEventLoop) + mock_rp = MagicMock(name="request_permission") + + future = MagicMock(spec=Future) + future.result.return_value = None + + with patch("acp_adapter.permissions.asyncio.run_coroutine_threadsafe", return_value=future): + cb = make_approval_callback(mock_rp, loop, session_id="s1", timeout=1.0) + result = cb("echo hi", "demo") + + assert result == "deny"