{"record":{"id":"97f9f9d712a90d90","repo":"agentscope-ai/agentscope","slug":"host-cache-dir-was-removed-or-replaced-before-exec","errorCode":null,"errorMessage":"host_cache_dir was removed or replaced before execution.","messagePattern":"host_cache_dir was removed or replaced before execution\\.","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py","lineNumber":491,"sourceCode":"                identity = self._directory_identity(path, label=label)\n            except ValueError as exc:\n                raise RuntimeError(\n                    f\"{label} was removed or replaced before execution.\",\n                ) from exc\n            if identity != expected_identity:\n                raise RuntimeError(\n                    f\"{label} was replaced before execution.\",\n                )\n\n        if self._host_cache_dir is None:\n            return\n        try:\n            identity = self._directory_identity(\n                self._host_cache_dir,\n                label=\"host_cache_dir\",\n            )\n        except ValueError as exc:\n            raise RuntimeError(\n                \"host_cache_dir was removed or replaced before execution.\",\n            ) from exc\n        if identity != self._host_cache_identity:\n            raise RuntimeError(\n                \"host_cache_dir was replaced before execution.\",\n            )\n\n    @staticmethod\n    def _directory_identity(\n        path: str,\n        *,\n        label: str,\n    ) -> tuple[int, int]:\n        \"\"\"Return a stable identity for a real directory mount source.\"\"\"\n        if os.path.islink(path) or not os.path.isdir(path):\n            raise ValueError(f\"{label} must be a real directory: {path}\")\n        stat_result = os.stat(path, follow_symlinks=False)\n        return stat_result.st_dev, stat_result.st_ino","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py#L473-L509","documentation":"The same removal/replacement guard applied specifically to host_cache_dir: at execution time, _directory_identity on the cache dir raised ValueError (it is now a symlink or missing), so the backend refuses to build the bwrap invocation.","triggerScenarios":"host_cache_dir being deleted, replaced by a symlink, or turned into a non-directory while the workspace object is still in use.","commonSituations":"Cache-cleaning scripts (e.g. `find /cache -delete`) running against the library's cache directory mid-session; cache dirs placed under /tmp subject to cleanup.","solutions":["Exclude the library's cache dir from cache-cleaners/tmp-cleaners, or move it to a stable location","Reconstruct the workspace after external cache wipes","Pre-create the cache dir with 0700 perms owned by the app and document it as persistent state"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"null","typeGuard":"null","tryCatchPattern":"except RuntimeError as e:\n    if 'host_cache_dir was removed' in str(e):\n        await rebuild_workspace_with_fresh_cache()","preventionTips":["Exclude the library's cache dir from cron cleaners","Pin the cache to a stable, app-owned location"],"tags":["bubblewrap","cache","toctou","mount"],"backgroundTag":"mount-source-disappeared","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}