{"version":"2.1.223","anchor":"sdk-stream-emits-a-permission-denied-system-message","canonical_anchor":"sdk-stream-emits-a-permission-denied-system-message","heading":"SDK stream emits a permission_denied system message","tier":"notice","area":"SDK","scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.223\/e\/sdk-stream-emits-a-permission-denied-system-message","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.223","markdown":"### SDK stream emits a `permission_denied` system message\n\nSDK clients now get an explicit system message when a tool call is denied instead of guessing.\n\n**What**\n\nThe control-protocol session can now push a system message to the SDK stream whenever a tool call is denied, so clients can react to denials instead of inferring them from the tool result.\n\n**Details**\n\n- New `emitPermissionDenied` method on the control-protocol session class enqueues a message with `type: \"system\"` and `subtype: \"permission_denied\"`.\n- Payload carries `tool_name`, `tool_use_id`, `agent_id`, `decision_reason_type`, a serialized `decision_reason`, the deny message, a uuid and the session id.\n- On the stdio `createCanUseTool` path it fires on any deny.\n- On the non-stdio path it fires only when a new helper confirms the `tool_use` id actually appears in the message content and the abort signal has not fired.\n\n**Evidence**\n\n`decision_reason_type`\n\n- Area: SDK\n- Names: `permission_denied`\n- Tier: You'll notice\n- Useful: 3\/5\n- Signal: 0\/5"}