{"record":{"id":"8720b2c71e2d6916","repo":"agentscope-ai/agentscope","slug":"bubblewrap-file-access-is-limited-to-sandbox-work","errorCode":null,"errorMessage":"Bubblewrap file access is limited to {SANDBOX_WORKDIR!r} and {SANDBOX_TMPDIR!r}: {path!r}","messagePattern":"Bubblewrap file access is limited to (.+?) and (.+?): (.+?)","errorType":"validation","errorClass":"PermissionError","httpStatus":null,"severity":"error","filePath":"src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py","lineNumber":600,"sourceCode":"            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":582,"sourceCodeEnd":604,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py#L582-L604","documentation":"After normalization, sandbox file access is restricted to the two writable roots: SANDBOX_WORKDIR and SANDBOX_TMPDIR. Any normalized path outside those trees raises PermissionError, e.g. '/etc/passwd' or '/var/log/x', even though they exist inside the container.","triggerScenarios":"read_file/write_file on any absolute path not under the sandbox workdir or tmpdir prefixes.","commonSituations":"Assuming the whole container filesystem is writable; using host paths like /home/user/... verbatim; agent models proposing system paths.","solutions":["Keep all file I/O under the sandbox workdir (typically /workspace)","Copy needed host files into the workspace before the sandbox session","Catch PermissionError and re-prompt the agent with the allowed roots"],"exampleFix":"# before\nawait ws.read_file('/etc/hostname')\n# after\nawait ws.run_command('cp /etc/hostname /workspace/hostname.txt')\nawait ws.read_file('/workspace/hostname.txt')","handlingStrategy":"validation","validationCode":"norm = posixpath.normpath(path)\nif not norm.startswith(('/workspace/', '/tmp/')):\n    raise ValueError(f'outside allowed sandbox roots: {norm}')","typeGuard":"def within_writable_roots(p: str) -> bool:\n    n = posixpath.normpath(p)\n    return n.startswith(('/workspace/', '/tmp/'))","tryCatchPattern":"except PermissionError as e:\n    if 'limited to' in str(e): copy file into workspace and retry","preventionTips":["Treat /workspace as the only writable root in app logic","Copy host files into the workspace at session start"],"tags":["bubblewrap","permission","sandbox-restrictions"],"backgroundTag":"path-outside-sandbox-root","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}