Skip to Content

Why does my OpenAI Agents SDK agent fail without raising an error?

Rius shows these runs as failed traces badged recovered: a step inside the run errored, something between that step and the root span caught the error, and the run finished OK. Open the trace, follow the highlighted path to the errored span, and read its exception. The pre-defined Swallowed Error alert fires on this pattern when the errored step is not a tool call, so you hear about it the next time.

How it works

Rius derives a trace’s status from its spans, not from what your agent reports. For an OpenAI Agents SDK agent, the openai integration records each model call as an LLM generation, and your observe wrappers add the root AGENT span and a TOOL span for each function tool. See the OpenAI Agents SDK integration for the full mapping.

A silent failure has one shape in those spans:

  • A child span, for example a model call, ends with an error.
  • Your code, or something between that span and the root, catches it and returns a fallback such as a canned answer or a cached value.
  • The root span finishes without an error of its own.

The trace status is then failed because a span errored, but the root finished clean, so the trace carries the recovered badge. The errors are still counted. Only the verdict changes.

The Swallowed Error alert uses the same reading. It fires when the root span finishes OK while at least the configured number of child steps that are not tool calls ended with an error. Errored tool calls do not count, because the model receives a failed tool call as the tool’s result and could act on it. It fires once per run, and only on finished traces.

Handoffs produce no span of their own. A sub-agent that crashes after a handoff shows up as the errored span nearest the failure, or as consecutive generations from different agents. Add an observe wrapper per agent entry if you want the handoff boundary visible.

Set it up

  1. Wrap the run entrypoint and each tool body with observe, using the TOOL kind for tools. Install with pip install "glassflow-rius[openai]" openai-agents. The OpenAI Agents SDK integration page covers this setup in full.
import rius from agents import Agent, Runner, function_tool, set_tracing_disabled from rius import SpanKind rius.init(api_key="ri_...", service_name="my-agent") set_tracing_disabled(True) @function_tool @rius.observe(kind=SpanKind.TOOL) def account_status(email: str) -> str: """Fetch a customer's account standing by email.""" return lookup(email) support_agent = Agent( name="support_agent", instructions="Answer support questions; check accounts with the tool.", tools=[account_status], model="gpt-5-mini", ) @rius.observe(name="handle-ticket", kind=SpanKind.AGENT) def handle_ticket(ticket: str) -> str: result = Runner.run_sync(support_agent, ticket) return str(result.final_output)
  1. Keep @function_tool outermost and observe on the function body. With the TOOL kind, the Tool Loop alert and the Tool entry in the All kinds menu see your tools. A bare observe makes a CHAIN span that neither sees.
  2. Open Traces in the console and look for rows with the recovered badge. You can also filter on the failed status. The Exploring traces page covers the list and filters.
  3. Open a recovered trace. In the waterfall, failed spans are highlighted along the path from the root to the error, and the detail panel for an error span leads with the exception and traceback. Press ]e to jump to the next failed span.
  4. For one kind of step across many runs, use the Spans tab, set All kinds to LLM, and filter by status.
  5. Open Alerts, find Swallowed Error and attach a channel (webhook, email or Slack). To watch one service on its own, use Narrow this alert and set Root service.

What you get

  • The exact errored span, with its exception and traceback, instead of a run that only looks successful.
  • A recovered badge on the trace list, so swallowed failures stand out from clean runs.
  • Retry chains collapsed into one row, such as fetch_article · 3 attempts · recovered, when every attempt but the last failed.
  • A Swallowed Error alert with a 5 minute window and a threshold of at least 1 errored child span. You can turn on Renotify to repeat the notification while a firing is open and unacknowledged.
  • Consistent Error Pattern as a companion alert. It fires when the same error in the same service and step repeats across at least 2 distinct traces, for example an expired provider key behind every model call.
  • Tool Loop for agents that repeat the same tool call with identical arguments, once your tools carry the TOOL kind.

When something else fits

Status and Swallowed Error react to errored spans. If the agent returns a wrong or empty answer and no span errored, the trace reads completed. Read the Input / Output tab of the LLM spans, and use Since previous llm call to see what each step added to the prompt. For broader signals, see Monitor AI agents in production and the custom alerts on cost, tokens, latency and errors.

Still stuck? Get help

Last updated on