{"record":{"id":"9078b03f6c810fcf","repo":"FoundationAgents/OpenManus","slug":"terminal-not-initialized","errorCode":null,"errorMessage":"Terminal not initialized","messagePattern":"Terminal not initialized","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"app/sandbox/core/terminal.py","lineNumber":330,"sourceCode":"            self.container.exec_run, cmd, environment=self.env_vars\n        )\n        return result.exit_code, result.output.decode(\"utf-8\")\n\n    async def run_command(self, cmd: str, timeout: Optional[int] = None) -> str:\n        \"\"\"Runs a command in the container with timeout.\n\n        Args:\n            cmd: Shell command to execute.\n            timeout: Maximum execution time in seconds.\n\n        Returns:\n            Command output as string.\n\n        Raises:\n            RuntimeError: If terminal not initialized.\n        \"\"\"\n        if not self.session:\n            raise RuntimeError(\"Terminal not initialized\")\n\n        return await self.session.execute(cmd, timeout=timeout or self.default_timeout)\n\n    async def close(self) -> None:\n        \"\"\"Closes the terminal session.\"\"\"\n        if self.session:\n            await self.session.close()\n\n    async def __aenter__(self) -> \"AsyncDockerizedTerminal\":\n        \"\"\"Async context manager entry.\"\"\"\n        await self.init()\n        return self\n\n    async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:\n        \"\"\"Async context manager exit.\"\"\"\n        await self.close()\n","sourceCodeStart":312,"sourceCodeEnd":347,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/sandbox/core/terminal.py#L312-L347","documentation":"AsyncDockerizedTerminal.execute() delegates to an internal DockerSession created in init(); calling execute() before init() (or after a failed init) hits this guard. The class is a lifecycle wrapper: init() creates the session, and the async context manager (__aenter__) is the supported way to guarantee ordering.","triggerScenarios":"Constructing AsyncDockerizedTerminal(container) and immediately calling execute() without await init(); init() raising in _ensure_workdir (error 48) and the caller still proceeding to execute().","commonSituations":"Skipping the context manager in quick scripts; swallowing an init() exception with a broad try/except and continuing; two coroutines sharing one terminal where one fails init first.","solutions":["Use the context manager: 'async with AsyncDockerizedTerminal(container, working_dir=\"/workspace\") as term: await term.execute(...)' — __aenter__ calls init().","Or call 'await term.init()' explicitly and treat any exception there as fatal; do not call execute() afterwards.","Check 'term.session is not None' as a cheap pre-condition in calling code that receives a terminal from elsewhere.","Close and rebuild the terminal after any init failure instead of reusing the half-initialized object."],"exampleFix":"# before\nterm = AsyncDockerizedTerminal(container)\nout = await term.execute(\"ls\")  # RuntimeError: Terminal not initialized\n\n# after\nasync with AsyncDockerizedTerminal(container) as term:\n    out = await term.execute(\"ls\")","handlingStrategy":"validation","validationCode":"if term.session is None:\n    await term.init()\nassert term.session is not None","typeGuard":"async def ensure_terminal(term: AsyncDockerizedTerminal) -> AsyncDockerizedTerminal:\n    if term.session is None:\n        await term.init()\n    return term","tryCatchPattern":"try:\n    out = await term.execute(cmd)\nexcept RuntimeError as e:\n    if 'Terminal not initialized' in str(e):\n        async with AsyncDockerizedTerminal(term.container, term.working_dir, term.env_vars) as term2:\n            out = await term2.execute(cmd)\n    else:\n        raise","preventionTips":["Use 'async with AsyncDockerizedTerminal(...)' so init is guaranteed.","Never reuse a terminal whose init() failed.","Check term.session is not None when receiving terminals from elsewhere."],"tags":["terminal","lifecycle","async","docker"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}