agentscope-ai/agentscope · error · PermissionError
path escapes writable Bubblewrap mounts: {path}
Error message
path escapes writable Bubblewrap mounts: {path} What it means
read_file inside the sandbox returns exit code 65 when the target path resolves outside the sandbox's writable bind mounts. The backend translates this into PermissionError to signal that the sandboxed shell refused to touch the path for containment reasons.
Source
Thrown at src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py:272
[
"sh",
"-c",
(
'resolved=$(realpath -e -- "$1") || exit 66; '
'case "$resolved" in '
"/workspace|/workspace/*|/tmp|/tmp/*) "
'cat -- "$resolved" ;; '
"*) exit 65 ;; "
"esac"
),
"sh",
sandbox_path,
],
)
if result.exit_code == 66:
raise FileNotFoundError(f"not found in Bubblewrap sandbox: {path}")
if result.exit_code == 65:
raise PermissionError(
f"path escapes writable Bubblewrap mounts: {path}",
)
if not result.ok():
raise RuntimeError(
"Bubblewrap read_file failed "
f"(exit {result.exit_code}): "
f"{result.stderr.decode(errors='replace')}",
)
return result.stdout
async def write_file(self, path: str, data: bytes) -> None:
"""Write raw bytes, refusing every symbolic-link final component."""
await self._write_via_cat(path, data)
async def write_stream(
self,
path: str,
stream: AsyncIterator[bytes],View on GitHub (pinned to e90f1c7592)
Solutions
- Use an absolute path under the sandbox workdir or tmpdir only
- Normalize and prefix-join relative paths with the sandbox workdir before calling read_file
- Treat PermissionError from read_file as a path-design bug, not a transient failure
Example fix
# before
await ws.read_file('../../etc/passwd')
# after
await ws.read_file('/workspace/notes.txt') Defensive patterns
Strategy: validation
Validate before calling
from pathlib import PurePosixPath
ALLOWED = ('/workspace/', '/tmp/')
norm = posixpath.normpath(path)
assert norm.startswith(ALLOWED), f'outside sandbox: {norm}' Type guard
null
Try / catch
except PermissionError as e:
if 'escapes writable' in str(e): reject_path(path) Prevention
- Reject '..' segments and non-workspace-prefixed paths before I/O
- Never pass host paths through to sandbox APIs
When it happens
Trigger: Calling read_file on a path like /etc/passwd or ../../etc/shadow — anything outside the writable SANDBOX_WORKDIR/SANDBOX_TMPDIR trees once normalized inside the sandbox.
Common situations: Passing host-absolute paths that don't exist in the sandbox view, or traversal sequences that escape the workspace root.
Related errors
- Bubblewrap workdir escapes basedir.
- Bubblewrap file access is limited to {SANDBOX_WORKDIR!r} and
- Unsafe upload path: {entry.path!r}
- Invalid blob key: {key!r}
- Blob key {key!r} escapes the root directory.
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/c08b4b3345bf4ac5.
Report an issue: GitHub.