FoundationAgents/OpenManus · error · RuntimeError
Failed to create working directory: {e}
Error message
Failed to create working directory: {e} What it means
AsyncDockerizedTerminal._ensure_workdir runs 'mkdir -p {working_dir}' inside the container via exec_run and wraps any docker APIError in this RuntimeError. mkdir -p rarely fails on its own, so the wrapped APIError usually indicates the exec itself failed: container not running, image lacks a shell (/bin/sh), permission denied at the parent, or an invalid working_dir string.
Source
Thrown at app/sandbox/core/terminal.py:300
Raises:
RuntimeError: If initialization fails.
"""
await self._ensure_workdir()
self.session = DockerSession(self.container.id)
await self.session.create(self.working_dir, self.env_vars)
async def _ensure_workdir(self) -> None:
"""Ensures working directory exists in container.
Raises:
RuntimeError: If directory creation fails.
"""
try:
await self._exec_simple(f"mkdir -p {self.working_dir}")
except APIError as e:
raise RuntimeError(f"Failed to create working directory: {e}")
async def _exec_simple(self, cmd: str) -> Tuple[int, str]:
"""Executes a simple command using Docker's exec_run.
Args:
cmd: Command to execute.
Returns:
Tuple of (exit_code, output).
"""
result = await asyncio.to_thread(
self.container.exec_run, cmd, environment=self.env_vars
)
return result.exit_code, result.output.decode("utf-8")
async def run_command(self, cmd: str, timeout: Optional[int] = None) -> str:
"""Runs a command in the container with timeout.
View on GitHub (pinned to 52a13f2a57)
Solutions
- Check container.status == 'running' (after container.reload()) before creating the terminal.
- Quote the path and validate it: f'mkdir -p "{self.working_dir}"' and reject paths with shell metacharacters at construction.
- For minimal images, use a base image with coreutils, or create the directory at image build time (WORKDIR /workspace in the Dockerfile).
- Read the embedded APIError — 404 means container gone (recreate it), 126/127 means missing binary or permission issue in the image.
Example fix
# before
await self._exec_simple(f"mkdir -p {self.working_dir}")
# after
await self._exec_simple(f'mkdir -p "{self.working_dir}"')
# plus, at the caller:
container.reload()
if container.status != "running":
raise RuntimeError(f"Container {container.id} is {container.status}; cannot init terminal") Defensive patterns
Strategy: try-catch
Validate before calling
container.reload()
if container.status != 'running':
raise RuntimeError(f'cannot init terminal: container is {container.status}')
import re
if re.search(r"[\s'\";&|]", working_dir.strip('/').split('/')[-1]):
raise ValueError(f'unsafe working_dir: {working_dir!r}') Try / catch
try:
async with AsyncDockerizedTerminal(container, working_dir='/workspace') as term:
...
except RuntimeError as e:
if 'Failed to create working directory' in str(e):
raise RuntimeError('terminal init failed (container dead, read-only fs, or bad path)') from e
raise Prevention
- Use a base image with coreutils; create WORKDIR in the Dockerfile.
- Quote the working_dir in the mkdir command.
- Treat init failure as fatal for the terminal — rebuild it.
When it happens
Trigger: init() called on a stopped/removed container; working_dir containing characters that break the shell line (spaces unquoted, leading -); minimal images (distroless/scratch) with no mkdir binary; read-only filesystem at the target.
Common situations: Container TTL expired before terminal init; distroless images used for sandboxing; working_dir like '/my workspace' passed unquoted; container root filesystem mounted read-only.
Related errors
- Maximum number of sandboxes ({self.max_sandboxes}) reached
- Failed to ensure Docker image: {config.image}
- Failed to create sandbox: {e}
- Failed to create sandbox: {e}
- Empty tar archive
AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15).
Data as JSON: /api/errors/bc5b900193607bce.
Report an issue: GitHub.