FoundationAgents/MetaGPT · error · ValueError

Invalid python code

Error message

Invalid python code

What it means

OutputParser.parse_python_code in metagpt/utils/common.py tries two DOTALL regexes to strip markdown fences and extract a python code block, validating each candidate with ast.parse. If neither pattern yields a non-empty snippet that parses as valid Python syntax, it raises ValueError('Invalid python code').

Source

Thrown at metagpt/utils/common.py:139

            # Convert string representation of list to a Python list using ast.literal_eval.
            tasks = ast.literal_eval(tasks_list_str)
        else:
            tasks = text.split("\n")
        return tasks

    @staticmethod
    def parse_python_code(text: str) -> str:
        for pattern in (r"(.*?```python.*?\s+)?(?P<code>.*)(```.*?)", r"(.*?```python.*?\s+)?(?P<code>.*)"):
            match = re.search(pattern, text, re.DOTALL)
            if not match:
                continue
            code = match.group("code")
            if not code:
                continue
            with contextlib.suppress(Exception):
                ast.parse(code)
                return code
        raise ValueError("Invalid python code")

    @classmethod
    def parse_data(cls, data):
        block_dict = cls.parse_blocks(data)
        parsed_data = {}
        for block, content in block_dict.items():
            # 尝试去除code标记
            try:
                content = cls.parse_code(text=content)
            except Exception:
                # 尝试解析list
                try:
                    content = cls.parse_file_list(text=content)
                except Exception:
                    pass
            parsed_data[block] = content
        return parsed_data

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Log the input text and run ast.parse on it manually to find the exact syntax error location.
  2. If truncated, increase max_tokens or shrink the prompt and regenerate.
  3. Ensure the code sits after a '```python' fence and is syntactically complete.
  4. If you already hold raw code without fences, skip this parser and use the code string directly.

Example fix

# before
OutputParser.parse_python_code('def f(:')  # raises Invalid python code

# after
OutputParser.parse_python_code('```python\ndef f():\n    pass\n```')
Defensive patterns

Strategy: validation

Validate before calling

import ast

def is_parseable_python(text: str) -> bool:
    try:
        ast.parse(text)
        return True
    except SyntaxError:
        return False

Try / catch

try:
    code = OutputParser.parse_python_code(text)
except ValueError:
    # regenerate with higher max_tokens; log text for diagnosis

Prevention

When it happens

Trigger: Passing prose with no code; passing fenced code whose body has a syntax error (ast.parse fails); a response truncated mid-code by max_tokens; code containing unclosed triple quotes or brackets; text where the '```python' fence is never closed.

Common situations: LLM output got cut off before the closing fence, leaving half a function that fails ast.parse; model emits pseudo-code or shell commands instead of python; the caller feeds arbitrary text into a method that assumes an LLM code response.

Related errors


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/7752d1ded079126d. Report an issue: GitHub.