# Debugging and Troubleshooting Errors During Agent Actions in MetaGPT

> Troubleshoot MetaGPT agent action errors with automated detection, LLM output parsing, and centralized logging. Resolve failures efficiently during agent execution.

- Repository: [FoundationAgents/MetaGPT](https://github.com/FoundationAgents/MetaGPT)
- Tags: how-to-guide
- Published: 2026-03-04

---

**MetaGPT provides a layered debugging architecture that combines automated error detection via the `DebugError` action, robust LLM output parsing through `CodeParser`, and centralized logging to automatically identify, diagnose, and resolve failures during agent execution.**

MetaGPT orchestrates complex multi-agent workflows where **debugging and troubleshooting errors during agent actions** is critical for maintaining pipeline reliability. When agents execute actions—whether running tests, parsing LLM responses, or interacting with external services—failures can emerge from malformed JSON, runtime exceptions, or infrastructure issues. The framework provides specialized utilities across [`metagpt/actions/debug_error.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py), [`metagpt/utils/common.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py), and [`metagpt/logs.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/logs.py) to surface, analyze, and automatically remediate these errors.

## Action-Level Debugging with DebugError

The `DebugError` action automates the debugging loop by reading test output, feeding failure logs to an LLM, and extracting corrected code. Located in [`metagpt/actions/debug_error.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py) (lines 50-77), this specialized `Action` implementation inspects test results, constructs structured prompts containing the failing code and error logs, and returns a fix.

```python

# https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py#L50-L77

class DebugError(Action):
    i_context: RunCodeContext = Field(default_factory=RunCodeContext)
    repo: Optional[ProjectRepo] = Field(default=None, exclude=True)

    async def run(self, *args, **kwargs) -> str:
        # Retrieve test output from the repository

        output_doc = await self.repo.test_outputs.get(filename=self.i_context.output_filename)
        if not output_doc:
            return ""

        # Parse the test runner summary

        output_detail = RunCodeResult.loads(output_doc.content)
        pattern = r"Ran (\d+) tests in ([\d.]+)s\n\nOK"
        if re.search(pattern, output_detail.stderr):
            return ""  # No failures detected

        # Pull source and test code to construct the prompt

        code_doc = await self.repo.srcs.get(filename=self.i_context.code_filename)
        test_doc = await self.repo.tests.get(filename=self.i_context.test_filename)
        prompt = PROMPT_TEMPLATE.format(
            code=code_doc.content,
            test_code=test_doc.content,
            logs=output_detail.stderr,
        )

        # Request fix from LLM and extract code block

        rsp = await self._aask(prompt)
        return CodeParser.parse_code(text=rsp)

```

When an action fails, adding `DebugError` to the role's workflow enables automatic error recovery. The action uses the base class `_aask` method to invoke the configured LLM and relies on `CodeParser.parse_code` to safely extract the corrected implementation from the LLM's markdown response.

## Safe LLM Output Extraction with CodeParser

Parsing LLM output is error-prone due to malformed JSON, missing fields, or inconsistent markdown formatting. The `CodeParser` class in [`metagpt/utils/common.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py) (lines 250-280) normalizes this process by splitting markdown documents into logical sections and extracting specific code blocks.

```python

# https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py#L250-L280

class CodeParser:
    @classmethod
    def parse_block(cls, block: str, text: str) -> str:
        blocks = cls.parse_blocks(text)
        for k, v in blocks.items():
            if block in k:
                return v
        return ""

    @classmethod
    def parse_blocks(cls, text: str):
        # Split on "##" headings to create logical sections

        blocks = text.split("##")
        block_dict = {}
        for block in blocks:
            if not block.strip():
                continue
            if "\n" not in block:
                block_title, block_content = block, ""
            else:
                block_title, block_content = block.split("\n", 1)
            block_dict[block_title.strip()] = block_content.strip()
        return block_dict

```

The `parse_blocks` method handles missing or extra headings gracefully, returning a deterministic dictionary of sections. When `DebugError` or any other action processes LLM responses, using `CodeParser.parse_code` (which internally leverages these utilities) guarantees robust extraction of Python code from markdown fences, preventing parsing failures from cascading into agent execution errors.

## Centralized Logging for Agent Actions

MetaGPT uses **loguru** for structured logging, configured through [`metagpt/logs.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/logs.py). The `define_log_level` function (lines 9-55) initializes loggers with both console and file handlers, enabling adjustable verbosity across the framework.

```python

# https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/logs.py#L9-L55

def define_log_level(print_level="INFO", logfile_level="DEBUG", name: str = None):
    global _print_level
    _print_level = print_level

    current_date = datetime.now()
    formatted_date = current_date.strftime("%Y%m%d")
    log_name = f"{name}_{formatted_date}" if name else formatted_date

    _logger.remove()
    _logger.add(sys.stderr, level=print_level)  # Console output

    _logger.add(METAGPT_ROOT / f"logs/{log_name}.txt", level=logfile_level)  # File output

    return _logger

logger = define_log_level()

```

For LLM-specific debugging, the `log_debug` function in [`metagpt/provider/general_api_base.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/provider/general_api_base.py) (lines 80-95) respects the `LLM_LOG` environment variable, emitting debug messages only when explicitly enabled.

```python

# https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/provider/general_api_base.py#L80-L95

LLM_LOG = os.environ.get("LLM_LOG", "debug")

def log_debug(message, **params):
    if _console_log_level() == "debug":
        logger.debug(message, **params)

```

**Enabling verbose logging:**

```python
import os
os.environ["LLM_LOG"] = "debug"  # Enable LLM debug output

from metagpt.provider.general_api_base import log_debug

log_debug("Sending request to LLM", method="POST", url=api_url)

```

This configuration captures every LLM request, file I/O operation, and exception trace in the per-run log file located at `logs/{date}.txt`, providing a complete audit trail for troubleshooting agent actions.

## Exception Handling Utilities

MetaGPT centralizes error handling in [`metagpt/utils/exceptions.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/exceptions.py) to ensure consistent error messages and stack trace preservation. The `handle_exception` function wraps low-level operations, logging the full context before re-raising enriched exceptions.

```python

# https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/exceptions.py

def handle_exception(e: Exception, context: str = ""):
    logger.error(f"Exception in {context}: {e}")
    raise

```

Every utility performing I/O—such as [`metagpt/utils/s3.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/s3.py) and [`metagpt/utils/file.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/file.py)—invokes `handle_exception` on unexpected errors. This guarantees that **debugging and troubleshooting errors during agent actions** always produces uniform log entries containing the exception type, message, and operational context, eliminating fragmented error handling across the codebase.

## Complete Debugging Workflow Example

The following pattern demonstrates how to integrate MetaGPT's debugging utilities into a custom role or test harness. This example combines `DebugError`, centralized logging, and repository abstraction to create a self-healing workflow.

```python

# example_debug_flow.py

import os
from metagpt.actions.debug_error import DebugError
from metagpt.utils.project_repo import ProjectRepo
from metagpt.provider.general_api_base import log_debug

# Enable verbose log output for troubleshooting

os.environ["LLM_LOG"] = "debug"

async def debug_failed_action():
    # 1️⃣ Prepare repository abstraction pointing to your local project

    repo = await ProjectRepo.from_path(root_path="my_project")

    # 2️⃣ Initialise DebugError with context from the failing test

    dbg = DebugError(
        i_context=RunCodeContext(
            code_filename="src/foo.py",
            test_filename="tests/test_foo.py",
            output_filename="outputs/run_test.txt",
        ),
        repo=repo,
    )

    # 3️⃣ Execute debugging action – returns revised source code or empty string

    fixed_code = await dbg.run()
    if not fixed_code:
        log_debug("No fix suggested – test passed or LLM could not parse logs")
        return

    # 4️⃣ Persist the suggested fix (optional)

    await repo.srcs.save(filename="src/foo_fixed.py", content=fixed_code)
    log_debug("Fixed code written to src/foo_fixed.py")

# To execute within an async event loop:

# import asyncio

# asyncio.run(debug_failed_action())

```

This workflow delivers **rich log records** for each execution step, **structured prompts** automatically built from failing test output, and **robust code extraction** via `CodeParser`, enabling agents to self-correct during runtime.

## Key Files for Debugging Agent Actions

| Path | Purpose |
|------|---------|
| [`metagpt/actions/debug_error.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py) | Core debugging action that reads test output, builds LLM prompts, and extracts fixes. |
| [`metagpt/utils/common.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py) | Contains `CodeParser` class for safe markdown and code block extraction from LLM responses. |
| [`metagpt/logs.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/logs.py) | Global logger configuration using loguru; controls console and file output streams. |
| [`metagpt/provider/general_api_base.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/provider/general_api_base.py) | Implements `log_debug` function respecting the `LLM_LOG` environment variable. |
| [`metagpt/utils/exceptions.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/exceptions.py) | Centralized exception handling with `handle_exception` for consistent error reporting. |
| [`metagpt/actions/action.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/action.py) | Base `Action` class defining `_aask` method used by `DebugError` for LLM invocation. |
| [`metagpt/utils/file_repository.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/file_repository.py) | File abstraction layer used by `DebugError` to retrieve source and test files. |

## Summary

MetaGPT's debugging ecosystem revolves around a **clear separation of concerns** that enables systematic **debugging and troubleshooting errors during agent actions**:

- **Action-level helpers** (`DebugError` in [`metagpt/actions/debug_error.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py)) automate the detection of test failures and generation of corrective code via LLM prompts.
- **Parsing utilities** (`CodeParser` in [`metagpt/utils/common.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py)) normalize markdown extraction, preventing malformed LLM responses from cascading into execution errors.
- **Central logging** (`log_debug` and `define_log_level`) provides fine-grained visibility into LLM interactions and file I/O through environment-controlled verbosity.
- **Exception wrappers** (`handle_exception` in [`metagpt/utils/exceptions.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/exceptions.py)) standardize error messages and preserve stack traces across the codebase.

By wiring these components together, you can automatically detect failures, request corrective code from the LLM, and safely apply patches—all while retaining a complete, searchable audit trail in per-run log files.

## Frequently Asked Questions

### How does MetaGPT automatically fix code when tests fail?

MetaGPT uses the `DebugError` action class located in [`metagpt/actions/debug_error.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/actions/debug_error.py) to automate error correction. When a test fails, `DebugError` retrieves the test output from the repository, constructs a structured prompt containing the failing code, test code, and error logs, then invokes the LLM via the `_aask` method. The response is parsed using `CodeParser.parse_code` to extract the corrected implementation, which can then be saved back to the project.

### What is the purpose of the CodeParser utility in MetaGPT?

`CodeParser` in [`metagpt/utils/common.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/common.py) provides deterministic extraction of markdown sections and code blocks from LLM responses. Its `parse_blocks` method splits text on `##` headings to create logical sections, while `parse_block` retrieves specific sections by title. This prevents parsing failures—such as malformed JSON or inconsistent markdown—from propagating through the agent pipeline, ensuring that actions like `DebugError` receive clean, extractable code regardless of LLM output variations.

### How can I enable verbose debugging output in MetaGPT?

Set the `LLM_LOG` environment variable to `"debug"` before importing MetaGPT modules. This activates the `log_debug` function in [`metagpt/provider/general_api_base.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/provider/general_api_base.py), which emits detailed debug messages about LLM requests and responses. Additionally, the `define_log_level` function in [`metagpt/logs.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/logs.py) configures loguru to write `DEBUG` level logs to `logs/{date}.txt` while controlling console verbosity separately via the `print_level` parameter.

### Where does MetaGPT handle exceptions to ensure consistent error reporting?

MetaGPT centralizes exception handling in [`metagpt/utils/exceptions.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/exceptions.py) through the `handle_exception` function. This utility wraps low-level operations (such as file I/O in [`metagpt/utils/file.py`](https://github.com/FoundationAgents/MetaGPT/blob/main/metagpt/utils/file.py) or S3 interactions) to log the full error context and stack trace before re-raising enriched exceptions. This ensures that **debugging and troubleshooting errors during agent actions** produces uniform log entries across the entire codebase, eliminating fragmented error handling patterns.