FoundationAgents/OpenManus · error · ToolError

Failed to write to {path} in sandbox: {str(e)}

Error message

Failed to write to {path} in sandbox: {str(e)}

What it means

Raised by SandboxFileOperator.write_file (app/tool/file_operators.py:121) when sandbox_client.write_file throws. Like read_file, it catches every exception and re-raises as ToolError, discarding the original traceback via `from None`. Typical root causes are missing parent directories, read-only filesystems, path escaping the sandbox's writable scope, or transport-level failures to the sandbox runtime.

Source

Thrown at app/tool/file_operators.py:121

        """Ensure sandbox is initialized."""
        if not self.sandbox_client.sandbox:
            await self.sandbox_client.create(config=SandboxSettings())

    async def read_file(self, path: PathLike) -> str:
        """Read content from a file in sandbox."""
        await self._ensure_sandbox_initialized()
        try:
            return await self.sandbox_client.read_file(str(path))
        except Exception as e:
            raise ToolError(f"Failed to read {path} in sandbox: {str(e)}") from None

    async def write_file(self, path: PathLike, content: str) -> None:
        """Write content to a file in sandbox."""
        await self._ensure_sandbox_initialized()
        try:
            await self.sandbox_client.write_file(str(path), content)
        except Exception as e:
            raise ToolError(f"Failed to write to {path} in sandbox: {str(e)}") from None

    async def is_directory(self, path: PathLike) -> bool:
        """Check if path points to a directory in sandbox."""
        await self._ensure_sandbox_initialized()
        result = await self.sandbox_client.run_command(
            f"test -d {path} && echo 'true' || echo 'false'"
        )
        return result.strip() == "true"

    async def exists(self, path: PathLike) -> bool:
        """Check if path exists in sandbox."""
        await self._ensure_sandbox_initialized()
        result = await self.sandbox_client.run_command(
            f"test -e {path} && echo 'true' || echo 'false'"
        )
        return result.strip() == "true"

    async def run_command(

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Create parent directories first via the command operator: `await operator.run_command(f'mkdir -p {parent}')` before write_file.
  2. Verify the target path is inside a writable sandbox location (e.g. /workspace or /tmp inside the container).
  3. Check sandbox disk space/quota and read-only mounts with a quick `df -h <dir>` run_command if writes repeatedly fail.
  4. If the error message indicates a transport/auth failure rather than a filesystem error, recreate the sandbox (_ensure_sandbox_initialized only creates when sandbox is falsy; a stale-but-set client will not be refreshed — recreate explicitly).

Example fix

// before
await sandbox_files.write_file('/workspace/out/gen/result.md', text)

// after
await sandbox_files.run_command('mkdir -p /workspace/out/gen')
await sandbox_files.write_file('/workspace/out/gen/result.md', text)
Defensive patterns

Strategy: try-catch

Validate before calling

parent = PurePosixPath(path).parent
await sandbox_files.run_command(f'mkdir -p {parent}')
await sandbox_files.write_file(path, content)

Try / catch

try:
    await sandbox_files.write_file(path, content)
except ToolError as e:
    if 'Read-only' in str(e) or 'Permission' in str(e):
        reroute_to_writable_dir(path)
    else:
        raise

Prevention

When it happens

Trigger: Calling write_file(path, content) when: (1) the parent directory of path does not exist in the sandbox, (2) the target is on a read-only mount or disk quota is exhausted, (3) the sandbox client cannot reach the sandbox runtime API after implicit creation, (4) the path collides with an existing directory.

Common situations: Agent writes generated artifacts to nested paths (e.g. /workspace/src/gen/out.txt) without mkdir -p first; sandboxes with size limits or tmpfs quotas; sandbox token/URL expired between calls; writing to paths like /etc or other non-writable container locations.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/3c55b02b6e90ca52. Report an issue: GitHub.