{"record":{"id":"adb3b8e6b27a35e8","repo":"agentscope-ai/agentscope","slug":"host-cache-dir-must-not-overlap-host-workdir-becau","errorCode":null,"errorMessage":"host_cache_dir must not overlap host_workdir because it is used as a Bubblewrap bind source.","messagePattern":"host_cache_dir must not overlap host_workdir because it is used as a Bubblewrap bind source\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/workspace/_bubblewrap/_bubblewrap_workspace.py","lineNumber":262,"sourceCode":"            self._ensure_cache_directory(\n                cache_root,\n                make_private=True,\n            )\n            path = os.path.join(\n                cache_root,\n                key,\n            )\n            make_private = True\n\n        if os.path.lexists(path) and os.path.islink(path):\n            raise ValueError(\"host_cache_dir must not be a symbolic link.\")\n        cache_dir = os.path.realpath(path)\n        try:\n            common = os.path.commonpath([workdir, cache_dir])\n        except ValueError:\n            common = \"\"\n        if common in (workdir, cache_dir):\n            raise ValueError(\n                \"host_cache_dir must not overlap host_workdir because it \"\n                \"is used as a Bubblewrap bind source.\",\n            )\n\n        self._ensure_cache_directory(\n            path,\n            make_private=make_private,\n        )\n        return os.path.realpath(path)\n\n    @staticmethod\n    def _ensure_cache_directory(\n        path: str,\n        *,\n        make_private: bool,\n    ) -> None:\n        \"\"\"Create a cache directory without accepting a symlink root.\"\"\"\n        if os.path.lexists(path) and os.path.islink(path):","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/workspace/_bubblewrap/_bubblewrap_workspace.py#L244-L280","documentation":"The cache directory is bind-mounted into the Bubblewrap sandbox separately from the workspace; if it overlapped the workspace path, nested/recursive binds would conflict. Realpaths are compared with commonpath and any containment (cache inside workdir or workdir inside cache) is rejected.","triggerScenarios":"host_cache_dir equal to host_workdir, a subdirectory of it, or a parent of it after realpath resolution — including when symlinks made the overlap non-obvious.","commonSituations":"Setting host_cache_dir to something like <workdir>/cache for convenience; default cache dir resolution colliding with a custom workdir; symlinked paths masking the overlap.","solutions":["Move host_cache_dir completely outside the workspace tree (e.g. ~/.cache/agentscope/<id>)","If you intended a private cache, omit host_cache_dir and let the workspace create its own","Re-check with os.path.realpath on both paths that they share no commonpath containment"],"exampleFix":"# before\nws = BubblewrapWorkspace(host_workdir=\"/tmp/ws\", host_cache_dir=\"/tmp/ws/cache\")\n# after\nws = BubblewrapWorkspace(host_workdir=\"/tmp/ws\", host_cache_dir=\"/tmp/ws-cache\")","handlingStrategy":"validation","validationCode":"import os\nw, c = os.path.realpath(workdir), os.path.realpath(cache_dir)\nif os.path.commonpath([w, c]) in (w, c):\n    raise ValueError(\"cache and workspace overlap\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep cache dirs in a separate tree from workspace dirs","Remember the check uses realpath: symlinks don't dodge it"],"tags":["bubblewrap","cache","workspace","path-overlap","bind-mount"],"backgroundTag":"overlapping-mount-paths","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}