How can I see retries and fallbacks for my AI agent?
Rius shows retries as one collapsed row in the trace tree, and it badges runs that finished clean after failed child spans as recovered. Each attempt has to be its own span, and failed attempts need an error status. The recovered badge appears in the trace list. The retry row and the failed-span highlight appear in the trace’s waterfall, and the exception in the span details.
How it works
Rius builds these views from the spans you send, so nothing is reported separately as a retry. Four things show up.
- Retry chains. In a trace, back-to-back calls of the same tool or step, with the same input, collapse into one row when every attempt but the last failed, such as
fetch_article · 3 attempts · recovered. A retry loop reads as one event instead of a wall of identical spans. Expand the row to see each attempt. - Recovered badge. A trace is
failedwhen at least one span has an OpenTelemetryERRORstatus, normally a recorded exception. If the root span finished without an error of its own, the trace gets a recovered badge. Child spans errored, the agent retried or fell back, and the run completed clean. The errors are still counted. Only the verdict changes. - Recovered with a guess. If the root span never arrived, there is no root verdict, and the badge reads recovered? to say the verdict is a guess.
- Failed path. In the waterfall, failed spans are highlighted along the path from the root to the error. For an error span, the detail panel leads with the exception and traceback.
A fallback to another model appears as another model call in the same trace. Each LLM span has a Model section with provider, requested and response model, tokens and cost, so you can see which model answered after the first one failed.
Set it up
- Send traces to Rius. Setup is covered in full in Monitor AI agents in production. The Python version is:
import rius
client = rius.init(
api_key="ri_...",
service_name="my-agent",
)- Make every attempt its own span. A retry shows as a chain only when each try is a separate span with the same name, kind and captured input, each starting after the previous one ended, and every attempt but the last ending in error. Rius reads spans, so an attempt that never becomes a span cannot appear in the chain.
- Give each failed attempt an
ERRORstatus with a recorded exception. Exceptions are recorded as standard OpenTelemetry span events. In the SDK’s scoped forms they also set theERRORstatus and anerror.typeon the span. Without an error status on the failed attempt, the trace stayscompletedand nothing marks the recovery. - Let the root span end without an error. That is what turns
failedinto recovered. If the root span also records an error, Rius treats the run as a genuine failure. - Open the trace in the console. The Exploring traces page covers the trace list, waterfall and span details. The Concepts page defines traces, spans and kinds if you are new to them.
To find these runs later, use the Traces page and filter by status failed, then look for the recovered badge. On the Spans tab, filter by kind (for example LLM or Tool) or by status. You can also add an attribute filter on any span attribute your agents send. Inside a trace, ]e and [e jump to the next or previous failed span, and ]l and [l jump between LLM spans.
What you get
- A single row per retry loop in the trace, with the attempt count and a recovered marker, and the individual attempts one click away.
- A clear split between runs that failed and runs that failed along the way but recovered. Child errors stay counted, so retries do not disappear from your error numbers.
- The path from the root to each failed attempt highlighted in the waterfall, with the exception and traceback in the detail panel.
- Per-call model, tokens and cost on LLM spans, so a fallback model’s usage and cost are visible next to the failed call. Costs are list-price estimates in US dollars.
- The same verdict through the Rius MCP server. Its trace tools report
statusandroot_status, andstatus=Errorwithroot_status=Okis the recovered reading.root_status=Errorselects the genuine failures.
When something else fits
- If a retry happens somewhere that never creates a span, Rius has nothing to show for it, so add a span around each attempt first.
- If you need to know whether a process is stuck rather than retrying, look at the instance status on the agents page. Heartbeats show liveness, not progress.