Skip to content

_safe_json_serialize in telemetry/tracing.py is not fully safe and can break tool execution when JSON serialization fails #5411

@busbaby

Description

@busbaby

Describe the Bug:
The _safe_json_serialize function in google/adk/telemetry/tracing.py is intended to safely serialize arbitrary Python objects for telemetry purposes without raising exceptions. However, it does not handle all failure modes of json.dumps, specifically ValueError (e.g., circular references) and RecursionError (deeply nested or recursive structures).

Because this function is invoked inside a finally block during tool execution telemetry emission, exceptions escaping this function can interrupt normal execution flow and potentially affect tool result handling.

Steps to Reproduce:

  1. Install google-adk
  2. Execute a tool call that produces a response object containing a circular reference or deeply nested recursive structure
    • Example: an object referencing itself directly or indirectly
  3. Allow telemetry tracing to execute _safe_json_serialize during trace_tool_call
  4. Observe exception propagation during serialization in telemetry emission context

Expected Behavior:
Telemetry serialization should never raise exceptions under any input. If serialization fails, it should degrade gracefully (e.g., return a placeholder string) without affecting tool execution flow.

Observed Behavior:
In certain cases (e.g., circular references or deeply nested structures), json.dumps raises ValueError or RecursionError, which are not caught by _safe_json_serialize. Since this function is called inside a finally block, the exception can interrupt execution flow and potentially replace or suppress the original function result.

Environment Details:

  • ADK Library Version (pip show google-adk): 1.25.1
  • Desktop OS: Ubuntu 24.04.4 LTS
  • Python Version (python -V): Python 3.12.3

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A

🟡 Optional Information

Providing this information greatly speeds up the resolution process.

Regression:
Unknown / N/A

Logs:

N/A - no explicit stack trace captured, failure occurs during telemetry serialization in finally block context

Screenshots / Video:
N/A

Additional Context:
The key concern is that telemetry serialization is executed inside a finally block during async tool execution. As a result, serialization failures can interfere with execution flow rather than being isolated to telemetry only. This creates coupling between observability and runtime correctness.

Minimal Reproduction Code:

class Node:
    def __init__(self):
        self.ref = self

obj = Node()

# Passing this object through a tool response or telemetry payload
# may trigger circular reference handling failure in json.dumps

How often has this issue occurred?:

  • Intermittently

Metadata

Metadata

Assignees

No one assigned

    Labels

    tracing[Component] This issue is related to OpenTelemetry tracing

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions