FoundationAgents/MetaGPT · error · ValueError

Could not find content between [{tag}] and [/{tag}]

Error message

Could not find content between [{tag}] and [/{tag}]

What it means

OutputParser.extract_content in metagpt/utils/common.py extracts text between [TAG] and [/TAG] markers (default tag 'CONTENT') using a non-greedy DOTALL regex. When either marker is absent from the input, the regex fails and this ValueError is raised.

Source

Thrown at metagpt/utils/common.py:166

                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

    @staticmethod
    def extract_content(text, tag="CONTENT"):
        # Use regular expression to extract content between [CONTENT] and [/CONTENT]
        extracted_content = re.search(rf"\[{tag}\](.*?)\[/{tag}\]", text, re.DOTALL)

        if extracted_content:
            return extracted_content.group(1).strip()
        else:
            raise ValueError(f"Could not find content between [{tag}] and [/{tag}]")

    @classmethod
    def parse_data_with_mapping(cls, data, mapping):
        if "[CONTENT]" in data:
            data = cls.extract_content(text=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:
                pass
            typing_define = mapping.get(block, None)
            if isinstance(typing_define, tuple):
                typing = typing_define[0]
            else:
                typing = typing_define

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Ensure the text literally contains both [CONTENT] and [/CONTENT] around the payload.
  2. If truncated, raise max_tokens or shorten the prompt so the closing marker fits.
  3. Verify the tag argument matches the marker actually used in the text, including case.
  4. Fall back to parse_data/parse_blocks if the input isn't marker-wrapped.

Example fix

# before
OutputParser.extract_content('the answer')  # raises

# after
OutputParser.extract_content('[CONTENT]the answer[/CONTENT]')  # -> 'the answer'
Defensive patterns

Strategy: validation

Validate before calling

def has_tag_markers(text: str, tag: str = "CONTENT") -> bool:
    return f"[{tag}]" in text and f"[/{tag}]" in text

Try / catch

try:
    content = OutputParser.extract_content(text, tag)
except ValueError:
    content = text  # fallback: use raw text when markers are absent

Prevention

When it happens

Trigger: extract_content('no markers here'); only the opening [CONTENT] present because the response was truncated before [/CONTENT]; a custom tag name that doesn't match what's in the text (e.g. tag='ANSWER' but text uses [RESULT]); nested or mismatched marker casing ([content] vs [CONTENT]).

Common situations: LLM omits the closing marker, exceeds max_tokens mid-answer, or paraphrases the markers. Also triggered when parse_data_with_mapping is fed data lacking the [CONTENT] wrapper entirely.

Related errors


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