{"record":{"id":"b39547dccb2eebb8","repo":"oraios/serena","slug":"project-with-path-project-root-was-already-added","errorCode":null,"errorMessage":"Project with path {project_root} was already added with name '{already_registered_project.project_name}'.","messagePattern":"Project with path (.+?) was already added with name '(.+?)'\\.","errorType":"exception","errorClass":"FileExistsError","httpStatus":null,"severity":"warning","filePath":"src/serena/config/serena_config.py","lineNumber":1270,"sourceCode":"        Adds a new project to the Serena configuration from a given path, auto-generating the project\n        with defaults if it does not exist.\n        Will raise a FileExistsError if a project already exists at the path.\n\n        :param project_root: the path to the project to add\n        :param asynchronous_autogen: whether to use asynchronous auto-generation for the project configuration\n        :return: the project that was added\n        \"\"\"\n        from ..project import Project\n\n        project_root = Path(project_root).resolve()\n        if not project_root.exists():\n            raise FileNotFoundError(f\"Error: Path does not exist: {project_root}\")\n        if not project_root.is_dir():\n            raise FileNotFoundError(f\"Error: Path is not a directory: {project_root}\")\n\n        for already_registered_project in self.projects:\n            if str(already_registered_project.project_root) == str(project_root):\n                raise FileExistsError(\n                    f\"Project with path {project_root} was already added with name '{already_registered_project.project_name}'.\"\n                )\n\n        autogen = ProjectConfigAutoGenerationMode.ASYNCHRONOUS if asynchronous_autogen else ProjectConfigAutoGenerationMode.SYNCHRONOUS\n        project_config = ProjectConfig.load(project_root, serena_config=self, autogen=autogen)\n\n        new_project = Project(\n            project_root=str(project_root),\n            project_config=project_config,\n            is_newly_created=True,\n            serena_config=self,\n        )\n        self.add_registered_project(RegisteredProject.from_project_instance(new_project))\n\n        return new_project\n\n    def remove_project(self, project_name: str) -> None:\n        # find the index of the project with the desired name and remove it","sourceCodeStart":1252,"sourceCodeEnd":1288,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/config/serena_config.py#L1252-L1288","documentation":"add_project_from_path() prevents duplicate registrations: if a project with the same resolved root path is already present in self.projects, it raises FileExistsError reporting the path and the name it was registered under. Registering the same directory twice would create duplicate project entries in serena_config.yml.","triggerScenarios":"Calling add_project_from_path('/repos/app') when '/repos/app' (or a path string that resolves identically) is already registered — including calling activate_project_from_path_or_name() with an already-registered path.","commonSituations":"Re-running an onboarding/activation script without idempotency; two code paths both adding the project during startup; equivalent paths like /repos/app vs /repos/../repos/app resolving to the same root (resolve() normalizes them).","solutions":["Before adding, scan config.projects for an entry whose project_root matches the resolved path and reuse it (get_registered_project(path)) instead of adding.","Catch FileExistsError and treat it as success: fetch the existing project via get_registered_project(project_root).","Remove the existing registration first with remove_project(existing.project_name) if you intend to re-add it fresh."],"exampleFix":"// before\nconfig.add_project_from_path('/repos/app')  # FileExistsError on rerun\n// after\ntry:\n    config.add_project_from_path('/repos/app')\nexcept FileExistsError:\n    project = config.get_registered_project('/repos/app')","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\nresolved = str(Path(project_root).resolve())\nalready = any(str(p.project_root) == resolved for p in config.projects)","typeGuard":"def is_registered(config, root) -> bool:\n    from pathlib import Path\n    r = str(Path(root).resolve())\n    return any(str(p.project_root) == r for p in config.projects)","tryCatchPattern":"try:\n    config.add_project_from_path(project_root)\nexcept FileExistsError:\n    project = config.get_registered_project(project_root)  # reuse existing","preventionTips":["Check is_registered() before every add_project_from_path call","Make registration scripts idempotent (add-or-get pattern)","Remember resolve() normalizes equivalent paths, so aliases still collide"],"tags":["configuration","duplicate","python"],"backgroundTag":"duplicate-registration","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}