{"record":{"id":"4bc1b6607b4f0ac6","repo":"oraios/serena","slug":"relative-path-points-outside-the-project-root","errorCode":null,"errorMessage":"{relative_path=} points outside the project root ({self.project_root})","messagePattern":"(.+?) points outside the project root \\((.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/project.py","lineNumber":341,"sourceCode":"        if require_file:\n            return exists and abs_path.is_file()\n        else:\n            return exists\n\n    def validate_relative_path(self, relative_path: str, require_not_ignored: bool = False) -> None:\n        \"\"\"\n        Validates that the given relative path is within the project directory\n        (and, optionally, not ignored according to the project's ignore settings),\n        raising a ValueError if the validation fails.\n\n        :param relative_path: the path to validate, relative to the project root\n        :param require_not_ignored: if True, the path must not be ignored according to the project's ignore settings\n        \"\"\"\n        if FileProxy.is_external_path(relative_path):\n            return\n\n        if not self.is_path_in_project(relative_path):\n            raise ValueError(f\"{relative_path=} points outside the project root ({self.project_root})\")\n\n        if require_not_ignored:\n            if self.is_ignored_path(relative_path):\n                raise ValueError(f\"Path {relative_path} is ignored\")\n\n    def gather_source_files(self, relative_path: str = \"\") -> list[str]:\n        \"\"\"Retrieves relative paths of all source files, optionally limited to the given path\n\n        :param relative_path: if provided, restrict search to this path\n        \"\"\"\n        rel_file_paths = []\n        start_path = os.path.join(self.project_root, relative_path)\n        if not os.path.exists(start_path):\n            raise FileNotFoundError(f\"Relative path {start_path} not found.\")\n        if os.path.isfile(start_path):\n            return [relative_path]\n        else:\n            for root, dirs, files in os.walk(start_path, followlinks=True):","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/project.py#L323-L359","documentation":"Raised by Project.validate_relative_path (src/serena/project.py:341) when a given relative path escapes the project root — i.e. is_path_in_project() is False. It prevents file operations (apply, file collection) from touching anything outside the project sandbox.","triggerScenarios":"Passing paths containing '..' components, absolute paths not under project_root (and not flagged as external), or symlinks resolving outside the project to validate_relative_path, apply, or _collect_files.","commonSituations":"Agents constructing '../other-repo/file.py' style paths; joining user-supplied absolute paths onto project_root; symlinked directories pointing outside the repo.","solutions":["Pass a path relative to the project root with no '..' components","If you intentionally need an outside file, use the external-path API (FileProxy external paths) instead of a project-relative path","Normalize the path (os.path.normpath) and check it stays under project_root before calling"],"exampleFix":"// before\nproject.validate_relative_path('../shared/config.py')\n// after\nrel = os.path.relpath('/abs/shared/config.py', project.project_root)\nif not rel.startswith('..'):\n    project.validate_relative_path(rel)","handlingStrategy":"validation","validationCode":"rel = os.path.normpath(rel)\nassert not rel.startswith('..') and not os.path.isabs(rel), 'path escapes project root'","typeGuard":null,"tryCatchPattern":"try:\n    project.validate_relative_path(rel, require_not_ignored=True)\nexcept ValueError as e:\n    logging.error('Invalid project-relative path: %s', e)\n    return None","preventionTips":["Keep all paths relative to project root","Reject user input containing '..'","Be aware of symlinks pointing outside the project","Normalize paths before validation"],"tags":["python","path","validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}