FoundationAgents/OpenManus · error · TimeoutError
Command '{cmd}' timed out after {timeout} seconds in sandbox
Error message
Command '{cmd}' timed out after {timeout} seconds in sandbox What it means
Raised by SandboxFileOperator.run_command (app/tool/file_operators.py:154) when the sandbox client raises TimeoutError executing a command. The default timeout is 120.0 seconds; the wrapper re-raises a new TimeoutError with the command text and the timeout value, chaining the original. All other exceptions degrade to a (1, '', 'Error executing command...') return value instead of raising.
Source
Thrown at app/tool/file_operators.py:154
)
return result.strip() == "true"
async def run_command(
self, cmd: str, timeout: Optional[float] = 120.0
) -> Tuple[int, str, str]:
"""Run a command in sandbox environment."""
await self._ensure_sandbox_initialized()
try:
stdout = await self.sandbox_client.run_command(
cmd, timeout=int(timeout) if timeout else None
)
return (
0, # Always return 0 since we don't have explicit return code from sandbox
stdout,
"", # No stderr capture in the current sandbox implementation
)
except TimeoutError as exc:
raise TimeoutError(
f"Command '{cmd}' timed out after {timeout} seconds in sandbox"
) from exc
except Exception as exc:
return 1, "", f"Error executing command in sandbox: {str(exc)}"
View on GitHub (pinned to 52a13f2a57)
Solutions
- Pass an explicit larger timeout: `await operator.run_command(cmd, timeout=600)`.
- Make the command non-interactive and bounded: add flags like `-y`, `--no-input`, `--max-time`, or `timeout 600 <cmd> && echo done` inside the command itself.
- For unbounded work, background it and poll: `nohup <cmd> > /tmp/log 2>&1 & echo $!` then check the log/process with subsequent run_command calls.
- Catch TimeoutError at the call site (it propagates as a real TimeoutError, not ToolError) and decide whether to retry, extend, or abort.
Example fix
// before
rc, out, err = await sandbox_files.run_command('npm install') # 120s default, times out
// after
rc, out, err = await sandbox_files.run_command('npm install --no-audit --no-fund', timeout=600) Defensive patterns
Strategy: try-catch
Validate before calling
timeout = timeout if timeout is not None else 120 # budget the call: run only commands you expect to finish well under `timeout`
Type guard
def has_bounded_timeout(cmd: str, timeout: float | None, expected_secs: int) -> bool:
return timeout is not None and timeout >= expected_secs * 1.5 and '<' not in cmd Try / catch
try:
rc, out, err = await sandbox_files.run_command(cmd, timeout=600)
except TimeoutError:
rc, out, err = 1, '', f'{cmd} exceeded budget; consider backgrounding' Prevention
- Always pass an explicit timeout sized to the command (installs/builds: 300-900s).
- Make commands non-interactive (-y, --no-input) so they cannot hang waiting for stdin.
- Background long jobs (nohup ... &) and poll their log instead of blocking run_command.
When it happens
Trigger: Calling run_command(cmd, timeout=N) (or omitting timeout, defaulting to 120s) where the command runs longer than the timeout: package installs (pip/npm), long builds, test suites, or commands that block waiting for input. Also triggered when timeout is passed as a falsy-but-non-None value, since `int(timeout) if timeout else None` disables the client timeout only for falsy values.
Common situations: CI/agent loops running `npm install` or `pytest` in a sandbox with the 120s default; commands that prompt interactively (apt-get without -y) and never terminate; overloaded sandbox hosts making trivial commands exceed the budget; forgetting to pass a larger timeout for known-slow steps.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Command execution timed out after {timeout or self.config.ti
- Failed to read {path} in sandbox: {str(e)}
- Failed to write to {path} in sandbox: {str(e)}
- password must be provided
- Maximum number of sandboxes ({self.max_sandboxes}) reached
AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15).
Data as JSON: /api/errors/9e5f7c1bdcd792e2.
Report an issue: GitHub.