{"record":{"id":"4f0848272949a105","repo":"FoundationAgents/MetaGPT","slug":"file-filename-already-exists","errorCode":null,"errorMessage":"File '{filename}' already exists.","messagePattern":"File '(.+?)' already exists\\.","errorType":"exception","errorClass":"FileExistsError","httpStatus":null,"severity":"error","filePath":"metagpt/tools/libs/editor.py","lineNumber":366,"sourceCode":"        self._check_current_file()\n\n        with self.current_file.open() as file:\n            total_lines = max(1, sum(1 for _ in file))\n        self.current_line = self._clamp(self.current_line - self.window, 1, total_lines)\n        output = self._cur_file_header(self.current_file, total_lines)\n        output += self._print_window(self.current_file, self.current_line, self.window)\n        return output\n\n    async def create_file(self, filename: str) -> str:\n        \"\"\"Creates and opens a new file with the given name.\n\n        Args:\n            filename: str: The name of the file to create. If the parent directory does not exist, it will be created.\n        \"\"\"\n        filename = self._try_fix_path(filename)\n\n        if filename.exists():\n            raise FileExistsError(f\"File '{filename}' already exists.\")\n        await awrite(filename, \"\\n\")\n\n        self.open_file(filename)\n        return f\"[File {filename} created.]\"\n\n    @staticmethod\n    def _append_impl(lines, content):\n        \"\"\"Internal method to handle appending to a file.\n\n        Args:\n            lines: list[str]: The lines in the original file.\n            content: str: The content to append to the file.\n\n        Returns:\n            content: str: The new content of the file.\n            n_added_lines: int: The number of lines added to the file.\n        \"\"\"\n        content_lines = content.splitlines(keepends=True)","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/tools/libs/editor.py#L348-L384","documentation":"Raised by Editor.create_file when the target path already exists (any filesystem entry: file, directory, or symlink). create_file is write-once by design; it will not truncate or overwrite existing content, so it refuses rather than destroying data.","triggerScenarios":"editor.create_file('a.py') when a.py already exists on disk; re-running a generation step that already created the file; passing a path that collides with an existing directory.","commonSituations":"Retry loops in agent workflows re-invoking create_file after a partial failure; scaffolding scripts run twice; idempotency expectations where the tool is deliberately non-idempotent.","solutions":["Check filename.exists() first and open_file instead when the file already exists","If regeneration is intended, delete or move the old file before create_file","Guard retries: only call create_file when the file is absent"],"exampleFix":"// before\neditor.create_file('src/new_module.py')  # FileExistsError\n\n// after\nif filename.exists():\n    editor.open_file(str(filename))\nelse:\n    editor.create_file(str(filename))","handlingStrategy":"validation","validationCode":"from pathlib import Path\nif Path(filename).exists():\n    editor.open_file(filename)\nelse:\n    editor.create_file(filename)","typeGuard":"def should_create(p: str) -> bool:\n    return not Path(p).exists()","tryCatchPattern":"try:\n    editor.create_file(filename)\nexcept FileExistsError:\n    editor.open_file(filename)","preventionTips":["Make create-then-open an idempotent helper used by all retries","Do not retry create_file blindly in agent loops; check existence first","Treat FileExistsError from create_file as 'already done', not as failure"],"tags":["editor","filesystem","idempotency","metagpt"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}