Skip to Content

Why does my LangChain agent fail without raising an error?

Rius shows a LangChain run that fails without raising an error as a failed trace badged recovered: a step span inside the run errored, but the root span finished OK. The LangChain integration records one span per step, so you can open the trace and see which step failed and what exception it carried. The Swallowed Error alert catches the same pattern the next time it happens. For the wider workflow, see Monitor AI agents in production.

How it works

The LangChain integration hooks LangChain’s callback system, so chains, agents and LangGraph nodes are traced. Each step gets its own span, typed by what it is:

  • Chains are CHAIN spans.
  • Tool invocations are TOOL spans.
  • Retrievers are RETRIEVER spans.
  • Model calls are LLM spans with model, tokens and messages.

The nesting follows your chain structure, so the trace reads like your execution graph.

Trace status comes from the spans, not from what your agent reports. A trace is failed when at least one span carries an OpenTelemetry ERROR status. If the root span finished without an error of its own, the trace is badged recovered. A child step errored, your code retried, fell back or caught the error, and the run completed clean. The errors are still counted, and only the verdict changes. If the root span never arrived, the badge reads recovered? because the verdict is a guess.

So a run that looks healthy from the outside usually has an errored step underneath. The two kinds of step behave differently:

  • A failed tool call is returned to the model as the tool’s result. The agent saw it and could act on it.
  • A failed model call, chain or retriever that your code catches is the swallowed kind. The run reports success while a step inside it failed.

Set it up

  1. Make sure the integration is on. Install it with pip install "glassflow-rius[langchain]" langchain, then call init before you run your chains. TypeScript setup is on the LangChain page, and every integration is listed under Integrations.
import rius rius.init(api_key="ri_...", service_name="my-agent") # build and run your chains exactly as before
  1. Open Traces in the console and filter the status to failed. Look for rows badged recovered. These are the runs that reported success while a step errored. The row shows the error count, so a run with a clean root and a non-zero error count is your suspect. The trace list refreshes automatically, newest first.

  2. Open the trace. In the waterfall, failed spans are highlighted along the path from the root to the error. Select the errored span. For an error span, the detail panel leads with the exception and traceback. Press ]e to jump to the next failed span.

  3. Read what kind of step it was. If it is an LLM, chain or retriever span, your code swallowed the error. If it is a TOOL span, the model received the failure as a result. A back-to-back retry of the same tool with the same input collapses into one row such as fetch_article · 3 attempts · recovered. Expand it to see each attempt.

  4. Use the Spans tab to find the pattern. Filter by kind with the All kinds menu, or by status, to list every failed model call or retriever across runs.

  5. Check the alert. Swallowed Error is a pre-defined alert. It fires once per run when the root span finishes OK and at least one child step that is not a tool call ended with an error. Only finished traces are evaluated. It has a 5 minute window and renotify is off by default, so it sends once. You can disable it but not delete it. To watch only one part of your workspace, narrow it by Root service with Narrow this alert on its details page, and attach the channel that should receive it.

What you get

  • A list of runs that looked successful but contained a failed step, marked recovered and found with one status filter.
  • The failing step’s exception and traceback, placed in the tree where it happened.
  • A clear split between failures the agent saw (tool calls) and failures your code hid (everything else).
  • Retry chains shown as one row, so a loop of failing attempts reads as one event.
  • A Swallowed Error firing the next time a LangChain run hides a failed model call, chain or retriever, one firing per run.
  • If the same error repeats, Consistent Error Pattern fires when the same error in the same service and step reaches 3 errored spans across at least 2 traces within 5 minutes. A single trace retrying one step never fires it on its own.

When something else fits

  • If no span errored at all and the answer is simply wrong, no error-based alert fires. Read each span’s Input / Output tab instead, where Since previous llm call shows what each step added to the prompt. If your privacy controls strip content, that tab says so, though timings, tokens and cost still show.
  • If tool failures are what you care about, Swallowed Error ignores them by design. Consistent Error Pattern covers repeated tool errors, and a custom alert on error rate can cover the rest.

Still stuck? Get help

Last updated on