# Multi-agent workflows to reproduce error logs and open PRs

> Source: <https://www.nishantjani.com/blog/error-log-pattern-analysis-is-hard-2/>
> Published: 2026-09-19 17:01:37+00:00

My previous post spoke about the importance of error logs and the need for building a catalog of unique errors - which is as important in the AI coding era as ever. In this post I discuss my approach to using [Claude dynamic workflows](https://code.claude.com/docs/en/workflows) to allow a series of purpose-built suite of agents to have a way to auto-fix errors by creating pull requests for you. This is primarily a reference implementation and I’d be happy to share the agents, harnesses and tools I’ve built to achieve this. Some assumptions I have made to build this:

- This workflow primarily focuses on **backend systems** .
- It is intended to serve as a **proactive** self-improving codebase - not a reactive one. Not intended to be initiated during a Severity 1 incident to “fix” an issue.
- **Replication of a bug is paramount** to fixing it. Isolated component tests and unit tests that can run in docker are mandatory.
- **Error logs indicate something needs fixing and human attention.** Malformed user inputs which are well handled, cache misses that have golden source of data to fallback and transient failures that are fixed with retries are common patterns we categorize as noise and should not[deserve an error log](https://www.nishantjani.com/blog/accurate-error-logs/) .
- This workflow will have **access to codebase, its logging vendor (via MCP) and alerting setup** (via MCP or via API) and you have a system that can feed you[high quality catalog of error log patterns](https://www.nishantjani.com/blog/error-log-pattern-analysis-is-hard/#step-1-error-log-catalog)

## The Workflow Steps[#](#the-workflow-steps)

### 1. Explore Step[#](#1-explore-step)

Four agents lay the foundation to decide if the error log is worth debugging:

- **`testing-landscape` agent:** Reads CLAUDE.md or AGENT.md to verify the codebase has unit or isolated component tests, and runs them to ensure the test suite actually executes cleanly.
- **`impact-analysis` agent:** Checks the blast radius of the error log pattern—how many customers are affected, and which hosts or clusters report the issue.
- **`contextual-log-check` agent:** Runs live queries to understand log structure, verifying that critical correlation IDs (`trace_id` ,`span_id` ) are present across surrounding lines.
- **`alert-presence` agent:** Checks for existing alerting coverage and defined thresholds around this symptom.

**Decision:** If the codebase lacks the required test scaffolding or log hygiene to triage reliably, the workflow halts and logs a readiness warning. We only proceed if the environment provides enough deterministic context to triage safely.

### 2. Triage[#](#2-triage)

Given we have high quality context in order to do basic triaging of our error, our `candidate-trace-selection-agent` will pick 3-5 different samples of the error log occurring on a different host, stage and users. This is to allow multiple parallel triaging agents to come up with the root cause of the error. We aim to determine if there are more than 1 underlying root cause (determined in the next step) to this symptom. The `triaging-agent` is fed knowledge from our exploration and traces selected by our dedicated agent to start correlating the codebase to the observed logs for a given trace to find possible root cause.

**Decision:** We then have our decision agent collate all the root causes and determine if there are multiple root causes or a single one. If there are multiple root causes, we will feed each root cause separately into the debugging phase as each will deserve its own action.

### 3. Debuggers[#](#3-debuggers)

Rather than handing the problem to a generic prompt, we route the issue to problem-domain expert debuggers based on the error signature (e.g., timeouts, connection pool exhaustion, serialization failures). This is where team or org-specific knowledge is baked in. For example, a timeout-focused debugger understands your service’s specific middleware stack, how its timeout budgets cascade, and which external dependencies dictate those bounds.

**Decision:** Each specialized debugger investigates the failure mechanism and identifies the exact boundary conditions needed to mock and isolate the bug. The orchestrator selects the highest-confidence diagnosis to advance.

### 4. Replicate[#](#4-replicate)

The `replication-agent` receives the diagnosed root cause and boundary conditions from the chosen debugger. Its sole job is to write a clean, deterministic reproduction test - verified using the repo’s native test framework (unit and/or Dockerized component test).

**Decision:** The replication result dictates the terminal path:

- **Replicated & fixable:** Route to code fix.
- **Replicated, but external dependency failure:** Cannot be patched directly in this service; route to alerting
- **Identified as expected/handled behavior:** The logic is correct, but the log severity is wrong; route to log downgrade.

### 5. Action[#](#5-action)

Dedicated agents execute the final path decided by the replication phase:

- **`fix-with-replication` agent:** Applies the code fix, ensures the new replication test passes alongside the existing test suite, and opens a PR with blast-radius context from impact analysis.
- **`alert` agent:** Proposes or provisions an alerting rule if the failure is unfixable internally but needs monitoring.
- **`downgrade-log` agent:** Opens a PR downgrading the noisy log level (e.g., ERROR to WARN/INFO) to clean up log catalogs and removes alerts if present.

## Conclusion[#](#conclusion)

This workflow has helped me bring a lot of clarity on legacy codebases by pairing automated fixes with mandatory test reproduction, highlighting alert gaps backed by real impact data, and systematically eliminating log noise. Key areas for iteration include optimizing token usage across parallel agents, expanding MCP tool capabilities, and improving end-to-end workflow observability.
