{"record":{"id":"187a02b9edc70340","repo":"FoundationAgents/MetaGPT","slug":"to-replace-appears-more-than-once-please-includ","errorCode":null,"errorMessage":"`to_replace` appears more than once, please include enough lines to make code in `to_replace` unique.","messagePattern":"`to_replace` appears more than once, please include enough lines to make code in `to_replace` unique\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/tools/libs/editor.py","lineNumber":891,"sourceCode":"        # FIXME: support replacing *all* occurrences\n\n        if to_replace == new_content:\n            raise ValueError(\"`to_replace` and `new_content` must be different.\")\n\n        # search for `to_replace` in the file\n        # if found, replace it with `new_content`\n        # if not found, perform a fuzzy search to find the closest match and replace it with `new_content`\n        file_name = self._try_fix_path(file_name)\n        with file_name.open(\"r\") as file:\n            file_content = file.read()\n\n        if to_replace.strip() == \"\":\n            if file_content.strip() == \"\":\n                raise ValueError(f\"The file '{file_name}' is empty. Please use the append method to add content.\")\n            raise ValueError(\"`to_replace` must not be empty.\")\n\n        if file_content.count(to_replace) > 1:\n            raise ValueError(\n                \"`to_replace` appears more than once, please include enough lines to make code in `to_replace` unique.\"\n            )\n        start = file_content.find(to_replace)\n        if start != -1:\n            # Convert start from index to line number\n            start_line_number = file_content[:start].count(\"\\n\") + 1\n            end_line_number = start_line_number + len(to_replace.splitlines()) - 1\n        else:\n\n            def _fuzzy_transform(s: str) -> str:\n                # remove all space except newline\n                return re.sub(r\"[^\\S\\n]+\", \"\", s)\n\n            # perform a fuzzy search (remove all spaces except newlines)\n            to_replace_fuzzy = _fuzzy_transform(to_replace)\n            file_content_fuzzy = _fuzzy_transform(file_content)\n            # find the closest match\n            start = file_content_fuzzy.find(to_replace_fuzzy)","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/tools/libs/editor.py#L873-L909","documentation":"Raised by Editor._edit_file_by_replace when the to_replace snippet occurs more than once in the file. Because the tool performs a single targeted replacement (a FIXME notes all-occurrences support is absent), an ambiguous match is rejected rather than replacing an arbitrary instance.","triggerScenarios":"Replacing a common snippet such as a blank line, 'pass', an import, or a repeated log statement that appears multiple times; short one-line replacements of boilerplate code.","commonSituations":"Agents replacing small/common lines; refactoring duplicated code where the target itself is the duplication; replacing a function signature that appears in both definition and calls.","solutions":["Widen to_replace with surrounding context lines until it is unique in the file","Include distinctive lines (function def, decorators, comments) in the snippet","For truly repeated instances, replace one-by-one with distinguishing context, or handle it outside this API"],"exampleFix":"// before\neditor.edit_file_by_replace(path, to_replace='return None\\n', new_content='return 0\\n')\n# 'return None' appears 3 times -> ValueError\n\n// after\neditor.edit_file_by_replace(path,\n    to_replace='def count():\\n    return None\\n',\n    new_content='def count():\\n    return 0\\n')","handlingStrategy":"validation","validationCode":"file_content = Path(path).read_text()\nif file_content.count(to_replace) > 1:\n    # widen context until unique\n    idx = file_content.find(to_replace)\n    # include neighboring lines around idx into to_replace before calling\n    raise ValueError('ambiguous replace — add context lines')\neditor.edit_file_by_replace(path, to_replace, new_content)","typeGuard":"def snippet_is_unique(path: str, snippet: str) -> bool:\n    return Path(path).read_text().count(snippet) == 1","tryCatchPattern":"try:\n    editor.edit_file_by_replace(path, to_replace, new_content)\nexcept ValueError as e:\n    if 'more than once' in str(e):\n        # expand to_replace with surrounding lines and retry once\n        raise","preventionTips":["Always include a few context lines around the code being replaced","Avoid replacing ultra-common lines ('pass', blank lines, imports) without context","Pre-check uniqueness with file_content.count(snippet) == 1 in your wrapper"],"tags":["editor","replace","ambiguity","metagpt"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}