Skip to content

Python: Exception text is exported on spans and logs even when enable_sensitive_data=False #9263

Closed

Description

Version

agent-framework-core 1.21.0 (latest on PyPI; also confirmed on main tip as of 2026-10-11), mcp 1.28.1, opentelemetry-sdk 1.43.0

Problem

With enable_instrumentation(enable_sensitive_data=False), tool arguments and results are correctly withheld. But the exception message is still exported in full on tool, agent, chat and workflow spans, and on an ERROR log record. Exception text often carries the very data the flag is meant to protect. For example, an MCP output-schema validation failure embeds the tool's whole structured result (web results with URLs and query strings) in the RuntimeError message (mcp/client/session.py:439). We see these in Application Insights AppExceptions and AppTraces.

Reproduction (1.21.0)

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from agent_framework.observability import OBSERVABILITY_SETTINGS, capture_exception, enable_instrumentation

enable_instrumentation(enable_sensitive_data=False)
assert OBSERVABILITY_SETTINGS.SENSITIVE_DATA_ENABLED is False

exporter = InMemorySpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
trace.set_tracer_provider(provider)

secret = "https://example.com/search?q=founder-secret-token&api_key=sk-live-TEST"
exc = RuntimeError(f"Invalid structured content returned by tool web_search: {secret}")
with trace.get_tracer("repro").start_as_current_span("execute_tool") as span:
    capture_exception(span, exc)

span = exporter.get_finished_spans()[0]
assert secret in (span.status.description or "")  # FAILS the intended posture — text is present

Observed with sensitive data off:

  • status.description = full repr(exc) including the secret URL
  • exception event exception.message = full message including the secret URL
  • error.type = RuntimeError (correct)

Code paths that ignore the flag

  1. agent_framework/observability.py capture_exception (~3191-3195): span.record_exception(exception) and span.set_status(..., description=repr(exception)). Used on chat, agent and workflow spans, on tool spans (_tools.py ~1177) and on workflows (_workflows/_workflow.py ~700).
  2. agent_framework/_tools.py ~1174-1178, function-invoke failure: capture_exception(...) plus logger.error(f"Function failed. Error: {exception}").
  3. agent_framework/_workflows/_workflow.py ~693-700 (and _workflows/_functional.py): span.add_event("workflow.error", {"error.message": str(exc), ...}).
  4. agent_framework/_mcp.py ~2888 (+ nearby): set_mcp_span_error(span, "tool_error", text or str(...)). Tool error result text becomes the span status description.

Precedent in the same codebase

The result-parser failure path (_tools.py ~1199-1210) already does the right thing. With SENSITIVE_DATA_ENABLED off it sets only error.type and StatusCode.ERROR, and logs "Function {name}: result parser failed." with no text.

Proposed change

Apply the same gating everywhere above. When SENSITIVE_DATA_ENABLED is False:

  • set error.type = exception class, and status ERROR with no description (or the class name);
  • do not call record_exception (or record it with exception.message omitted, keeping exception.type);
  • omit error.message from workflow.error events;
  • log "Function {name} failed ({type})" without the message;
  • set the MCP tool_error status description to the error code or class only.

Diagnosability is kept through error.type, span status and the class name. Full text stays available when a developer opts into sensitive data.

Impact

Hosts that deliberately run with sensitive-data capture off (production / regulated environments) currently still leak tool-result and exception payload text into standard App Insights tables via span exception events and status descriptions.

Happy to open a PR that mirrors the result-parser gating pattern.

Activity

  1. added
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 11, 2026
  2. changed the title [-]Exception text is exported on spans and logs even when enable_sensitive_data=False[/-] [+]Python: Exception text is exported on spans and logs even when enable_sensitive_data=False[/+] on Oct 11, 2026
  3. scott-lever commented on Oct 11, 2026

    @scott-lever
    Author

    Also raised as an Azure Support case under AI Foundry Portal → Agent Framework / Agent orchestration issues:

    • Support ticket ID: 2610110050000926
    • Name: cfx13818-af-exception-sensitive-data-202610111914
    • Severity: Moderate (Standard plan)

    Confirmed still present on agent-framework-core==1.21.0 and current main (capture_exception writes full repr(exc) into span status / exception events with enable_sensitive_data=False).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

pythonUsage: [Issues, PRs], Target: Python

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions