Skip to content

feat: centralized outbound message sanitization gate #16673

@dahifi

Description

@dahifi

Problem

The current error sanitization is scattered across multiple per-tool and per-error-type handlers (sanitizeUserFacingText, formatAssistantErrorText, individual tool error formatting). Each new tool or API integration can introduce new leak vectors that require patching individually. This doesn't scale.

PR #16653 patches three specific variants (Brave Search 429, Edit tool path leaks, generic API error JSON), but the underlying architecture remains fragile.

Proposed Solution

Add a single sanitization gate in src/infra/outbound/deliver.ts at the deliverOutboundPayloads() boundary — every payload.text gets sanitized before hitting any channel send function, regardless of source (tool error, LLM error, assistant reply, system event).

Architecture

Current:  Tool errors → payloads.ts (per-tool sanitization) → deliver.ts → channels
Proposed: Tool errors → payloads.ts (raw) → deliver.ts (central sanitizer) → channels
                                                    ↓
                                              audit log (raw error for debugging)

Scope estimate (~70 net lines)

  • Add sanitizeOutboundText() in deliver.ts before channel sends (~20 lines)
  • Move/refactor sanitizeUserFacingText() to be outbound-aware (~30 lines)
  • Remove redundant per-tool sanitization (~-50 lines)
  • Emit raw errors to logging/audit before sanitizing (~40 lines)
  • Tests for the boundary sanitizer (~30 lines)

Benefits

  • Single point of control — new tools/APIs are safe by default
  • Audit trail — raw errors preserved for debugging, never shown to users
  • Simpler tool code — tools don't need to worry about error formatting

Related: #7867, PR #16653

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions