{"record":{"id":"ac6b903796fd37fb","repo":"FoundationAgents/MetaGPT","slug":"could-not-find-content-between-tag-and-tag","errorCode":null,"errorMessage":"Could not find content between [{tag}] and [/{tag}]","messagePattern":"Could not find content between \\[(.+?)\\] and \\[/(.+?)\\]","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/utils/common.py","lineNumber":166,"sourceCode":"                content = cls.parse_code(text=content)\n            except Exception:\n                # 尝试解析list\n                try:\n                    content = cls.parse_file_list(text=content)\n                except Exception:\n                    pass\n            parsed_data[block] = content\n        return parsed_data\n\n    @staticmethod\n    def extract_content(text, tag=\"CONTENT\"):\n        # Use regular expression to extract content between [CONTENT] and [/CONTENT]\n        extracted_content = re.search(rf\"\\[{tag}\\](.*?)\\[/{tag}\\]\", text, re.DOTALL)\n\n        if extracted_content:\n            return extracted_content.group(1).strip()\n        else:\n            raise ValueError(f\"Could not find content between [{tag}] and [/{tag}]\")\n\n    @classmethod\n    def parse_data_with_mapping(cls, data, mapping):\n        if \"[CONTENT]\" in data:\n            data = cls.extract_content(text=data)\n        block_dict = cls.parse_blocks(data)\n        parsed_data = {}\n        for block, content in block_dict.items():\n            # 尝试去除code标记\n            try:\n                content = cls.parse_code(text=content)\n            except Exception:\n                pass\n            typing_define = mapping.get(block, None)\n            if isinstance(typing_define, tuple):\n                typing = typing_define[0]\n            else:\n                typing = typing_define","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/utils/common.py#L148-L184","documentation":"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.","triggerScenarios":"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]).","commonSituations":"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.","solutions":["Ensure the text literally contains both [CONTENT] and [/CONTENT] around the payload.","If truncated, raise max_tokens or shorten the prompt so the closing marker fits.","Verify the tag argument matches the marker actually used in the text, including case.","Fall back to parse_data/parse_blocks if the input isn't marker-wrapped."],"exampleFix":"# before\nOutputParser.extract_content('the answer')  # raises\n\n# after\nOutputParser.extract_content('[CONTENT]the answer[/CONTENT]')  # -> 'the answer'","handlingStrategy":"validation","validationCode":"def has_tag_markers(text: str, tag: str = \"CONTENT\") -> bool:\n    return f\"[{tag}]\" in text and f\"[/{tag}]\" in text","typeGuard":null,"tryCatchPattern":"try:\n    content = OutputParser.extract_content(text, tag)\nexcept ValueError:\n    content = text  # fallback: use raw text when markers are absent","preventionTips":["Instruct the model to always wrap output in [CONTENT]...[/CONTENT].","Check for the closing marker to detect truncated responses."],"tags":["metagpt","llm-output","parsing","markers","truncation"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}