{"record":{"id":"331de4b02c09bf42","repo":"oraios/serena","slug":"error-path-is-not-a-directory-project-root","errorCode":null,"errorMessage":"Error: Path is not a directory: {project_root}","messagePattern":"Error: Path is not a directory: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"src/serena/config/serena_config.py","lineNumber":1266,"sourceCode":"        self._persist_projects()\n\n    def add_project_from_path(self, project_root: Path | str, asynchronous_autogen: bool = False) -> \"Project\":\n        \"\"\"\n        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","sourceCodeStart":1248,"sourceCodeEnd":1284,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/config/serena_config.py#L1248-L1284","documentation":"add_project_from_path() only registers directories, not files. After confirming existence, it checks Path.is_dir() and raises FileNotFoundError with 'Error: Path is not a directory' when the resolved path points to a regular file, symlink-to-file, or other non-directory.","triggerScenarios":"Calling add_project_from_path('/repos/app/README.md') or passing a file path to activate_project_from_path_or_name(); e.g. passing a config file path instead of the project root.","commonSituations":"Passing serena_project.yml itself instead of its parent directory; a broken symlink resolving to a file; shell autocompletion picking a file; scripts concatenating paths incorrectly.","solutions":["Pass the project root directory, not a file — if you have a config file path, use its .parent.","Guard the call: resolve the path and assert p.is_dir() before registering.","Check for stray symlinks/files where you expect the project directory."],"exampleFix":"// before\nconfig.add_project_from_path('/repos/app/serena_project.yml')\n// after\np = Path('/repos/app/serena_project.yml')\nconfig.add_project_from_path(p.parent)","handlingStrategy":"validation","validationCode":"from pathlib import Path\nroot = Path(project_root).expanduser().resolve()\nif not root.is_dir():\n    if root.is_file():\n        root = root.parent  # use the containing directory","typeGuard":"def is_directory(p) -> bool:\n    from pathlib import Path\n    return Path(p).expanduser().resolve().is_dir()","tryCatchPattern":"try:\n    config.add_project_from_path(project_root)\nexcept FileNotFoundError as e:\n    if 'not a directory' in str(e):\n        config.add_project_from_path(Path(project_root).parent)\n    else:\n        raise","preventionTips":["Never pass file paths (e.g. serena_project.yml) where a project root is expected","Use path.parent when starting from a config-file path","Check is_dir(), not just exists(), in pre-flight validation"],"tags":["filesystem","file-not-found","path","python"],"backgroundTag":"not-a-directory","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}