The SDK isolates sensitive data in exceptions using a redaction boundary that wraps awaitable factories and detects cancellation signals marked with _RedactedExceptionCancellationError, enabling rejection of outputs before their traceback payloads can leak. Redaction implements defensive patterns — reading exception state via BaseException.__reduce__, comparing dict keys with identity-level string operations, and keeping the boundary itself synchronous — to avoid triggering attacker-controlled descriptors or leaving partially-sanitized state in async suspension.
src/agents/exceptions.py imports BaseExceptionGroup from the exceptiongroup backport package on Python < 3.11, and uses the built-in builtins.BaseExceptionGroup on Python 3.11+.[1] _RedactedExceptionCancellationError in src/agents/exceptions.py is a private exception class that inherits from both asyncio.CancelledError and Exception, making it catchable as a plain Exception while still acting as a cancellation signal.[1] _data_redacted_sync_cancellation_source in src/agents/run.py detects a _RedactedExceptionCancellationError wrapped inside another CancelledError — a Python 3.10 pattern — and returns the inner marked error, enabling safe error-boundary handling.[2]
_await_data_redacted_error_boundary in src/agents/exceptions.py accepts an awaitable_factory callable rather than a pre-built awaitable, so that the factory is invoked inside the try block, preventing accidental capture of payload data before the boundary is established.[1] OutputGuardrailBlockedMessageFormatter in src/agents/run_config.py is intentionally synchronous: awaiting application code at the redaction boundary can leave rejected output reachable through cancellation traceback locals or partially sanitized state, so async support requires a full redesign of the redaction boundary rather than simply awaiting the formatter result.[3]
_base_exception_instance_dict in src/agents/exceptions.py reads built-in exception instance state via BaseException.__reduce__ specifically to avoid invoking subclass attribute descriptors that could be attacker-controlled.[1] _exact_string_state_entry in src/agents/exceptions.py iterates the raw exception state dict using identity-level string comparison — type(candidate) is str and str.__eq__ — to avoid triggering any custom __hash__ or __eq__ on attacker-supplied keys.[1]
Sources