{"record":{"id":"fdd300d0d79da046","repo":"agentscope-ai/agentscope","slug":"sandbox-path-must-be-absolute-path-r","errorCode":null,"errorMessage":"Sandbox path must be absolute: {path!r}","messagePattern":"Sandbox path must be absolute: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py","lineNumber":590,"sourceCode":"            \"/etc/group\",\n        ):\n            if os.path.exists(path):\n                args.extend([\"--ro-bind\", path, path])\n        for path in (\n            \"/etc/alternatives\",\n            \"/etc/ssl\",\n            \"/etc/pki\",\n            \"/etc/ca-certificates\",\n        ):\n            if os.path.exists(path):\n                args.extend([\"--ro-bind\", path, path])\n        return args\n\n    def _sandbox_path_for(self, path: str) -> str:\n        \"\"\"Validate and normalize a writable sandbox path.\"\"\"\n        sandbox_path = PurePosixPath(path)\n        if not sandbox_path.is_absolute():\n            raise ValueError(f\"Sandbox path must be absolute: {path!r}\")\n\n        normalized = posixpath.normpath(path)\n        for sandbox_root in (SANDBOX_WORKDIR, SANDBOX_TMPDIR):\n            if normalized == sandbox_root:\n                return normalized\n            prefix = sandbox_root + \"/\"\n            if normalized.startswith(prefix):\n                return normalized\n\n        raise PermissionError(\n            \"Bubblewrap file access is limited to \"\n            f\"{SANDBOX_WORKDIR!r} and {SANDBOX_TMPDIR!r}: {path!r}\",\n        )\n","sourceCodeStart":572,"sourceCodeEnd":604,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py#L572-L604","documentation":"_sandbox_path_for normalizes every path used for sandbox reads/writes and requires it to be absolute. Relative paths are ambiguous inside the container (whose CWD differs from the host), so the API rejects them immediately with ValueError.","triggerScenarios":"Calling read_file/write_file with 'out.txt', './data.csv', or any path not starting with '/'.","commonSituations":"Porting host-side code that used relative paths with os.getcwd(); concatenating a bare filename onto an API that expects a full sandbox path.","solutions":["Prefix relative names with the sandbox workdir constant to build an absolute path","Use PurePosixPath(workdir) / name to join safely","Validate paths are absolute before calling the API"],"exampleFix":"# before\nawait ws.read_file('results.json')\n# after\nawait ws.read_file('/workspace/results.json')","handlingStrategy":"type-guard","validationCode":"assert PurePosixPath(path).is_absolute(), f'need absolute sandbox path: {path}'","typeGuard":"def is_absolute_sandbox_path(p: str) -> bool:\n    return PurePosixPath(p).is_absolute()","tryCatchPattern":"except ValueError as e:\n    if 'must be absolute' in str(e):\n        path = str(PurePosixPath('/workspace') / path); retry","preventionTips":["Always join filenames onto the workdir constant before I/O","Never pass CWD-relative paths to sandbox APIs"],"tags":["bubblewrap","relative-path","validation"],"backgroundTag":"path-must-be-absolute","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}