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

  1. Pass an explicit larger timeout: `await operator.run_command(cmd, timeout=600)`.
  2. 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.
  3. For unbounded work, background it and poll: `nohup <cmd> > /tmp/log 2>&1 & echo $!` then check the log/process with subsequent run_command calls.
  4. 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

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

Related errors


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