Skip to content

Control flow exceptions like CallDeferred shouldn't be recorded as errors/exceptions in the running tool span #4530

@alexmojaki

Description

@alexmojaki

Initial Checks

Description

Previously pydantic/logfire#1515

All exceptions are being automatically caught and recorded as errors by tracer.start_as_current_span. But CallDeferred and ApprovalRequired aren't really errors. They show up as red in the logfire UI. And this isn't good for other OTel backends either. So exceptions need to be handled more manually for the running tool span.

Some queries may be checking for these exceptions already, so this should be changed in a new InstrumentationSettings version.

The exception and metadata should also be recorded (regardless of InstrumentationSettings version) as new regular span attributes on the span so that there's an alternative way to query this info.

Minimal, Reproducible Example

from pydantic_ai import Agent, DeferredToolRequests, CallDeferred
import logfire

logfire.configure()
logfire.instrument_pydantic_ai()

agent = Agent("openai:gpt-5.2", output_type=[DeferredToolRequests, str])

@agent.tool_plain
def delete_file(path: str) -> str:
    raise CallDeferred()

r1 = agent.run_sync("Delete `__init__.py`.")

Logfire Trace

https://logfire-us.pydantic.dev/public-trace/3019d079-5180-4a90-9bee-c79a768da800?spanId=0be27062195bb9d3

Python, Pydantic AI & LLM client version

Pydantic AI 1.63.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    OpenTelemetrybugReport that something isn't working, or PR implementing a fixgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions