ReAct Pattern: Interleaving Reasoning and Action for LLM Agents › Error Handling and Reliability

Michael BrenndoerferFebruary 3, 20263 min read
Language AI HandbookAll chapters
Part 48 of 67Tool Use and Agents
Chapter 365ReAct Pattern: Interleaving Reasoning and Action for LLM Agents › Error Handling and Reliability
Reading section 10 of 14 · Error Handling and Reliability · 3 minSection 10 of 14 · 3 min

Book contents

Section 10 of 14 · 3 min read

ReAct Pattern: Interleaving Reasoning and Action for LLM Agents › Error Handling and ReliabilityOne section · Sections in this chapter10 / 14 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Real-world ReAct implementations must handle several failure modes that can disrupt the reasoning loop or lead to incorrect conclusions. These are not edge cases: they occur frequently in production, and an agent that cannot handle them gracefully will fail on a substantial fraction of queries.

Invalid Action Parsing

When the model generates malformed actions, for example search[query with a missing closing bracket, the system should return a helpful error observation that prompts the model to correct the syntax in the next iteration. The error message should be explicit and directive:

Observation: Error: Could not parse action. Expected format: search[your query here]. Please retry with correct bracket syntax.

This phrasing tells the model exactly what went wrong and how to fix it. A vague error like "invalid input" often leads the model to try increasingly divergent formats before eventually giving up. Specific error messages lead to faster recovery.

Tool Execution Failures

External APIs timeout, databases return connection errors, and calculations occasionally overflow or divide by zero. These exceptions should be caught gracefully and returned as observations so the model can adapt its strategy. The error handling should distinguish between transient failures (network timeout, rate limit) and permanent ones (invalid query syntax, resource not found). For transient failures, the observation can suggest a retry. For permanent failures, it should suggest an alternative approach.

Reasoning Loops

The model might enter cycles, repeatedly searching for the same information or alternating between two equivalent states without making progress. You can detect this by tracking the action history: if the same action appears twice in the trajectory, note the repetition in the next prompt.

A simple loop-detection mechanism:

In[11]:
Code
def detect_loop(trajectory: List[Dict[str, str]], window: int = 3) -> bool:
    """Check if the agent is repeating actions within the last `window` steps."""
    if len(trajectory) < window:
        return False
    recent_actions = [step["action"] for step in trajectory[-window:]]
    return len(set(recent_actions)) < len(recent_actions)

When a loop is detected, the observation for the repeated action can include a nudge: "This search was already performed in step 2. Consider trying a different search term or checking whether you already have enough information to answer."

Hallucinated Facts in Thoughts

While observations provide grounding for the final answer, the thoughts themselves can contain reasoning errors or false assumptions. A model might write "Hemingway lived in Paris for many years, so his birthplace is likely France" as a thought, then search based on that incorrect assumption. The observation corrects it, but only if the model pays attention.

Advanced systems address this by using self-consistency sampling: running the ReAct loop multiple times with different random seeds and checking whether the trajectories agree on intermediate facts. When trajectories diverge on a sub-question, that sub-question gets flagged for extra verification. This is expensive but useful for high-stakes applications.