{"record":{"id":"1fdb11c5a334ce13","repo":"FoundationAgents/OpenManus","slug":"session-has-not-started","errorCode":null,"errorMessage":"Session has not started.","messagePattern":"Session has not started\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"app/tool/bash.py","lineNumber":50,"sourceCode":"        if self._started:\n            return\n\n        self._process = await asyncio.create_subprocess_shell(\n            self.command,\n            preexec_fn=os.setsid,\n            shell=True,\n            bufsize=0,\n            stdin=asyncio.subprocess.PIPE,\n            stdout=asyncio.subprocess.PIPE,\n            stderr=asyncio.subprocess.PIPE,\n        )\n\n        self._started = True\n\n    def stop(self):\n        \"\"\"Terminate the bash shell.\"\"\"\n        if not self._started:\n            raise ToolError(\"Session has not started.\")\n        if self._process.returncode is not None:\n            return\n        self._process.terminate()\n\n    async def run(self, command: str):\n        \"\"\"Execute a command in the bash shell.\"\"\"\n        if not self._started:\n            raise ToolError(\"Session has not started.\")\n        if self._process.returncode is not None:\n            return CLIResult(\n                system=\"tool must be restarted\",\n                error=f\"bash has exited with returncode {self._process.returncode}\",\n            )\n        if self._timed_out:\n            raise ToolError(\n                f\"timed out: bash has not returned in {self._timeout} seconds and must be restarted\",\n            )\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/tool/bash.py#L32-L68","documentation":"Persistent bash tool session guard: stop() raises ToolError if _started is False, i.e. start() never spawned the bash process. stop() is meant to terminate a live shell; calling it on a session that was constructed but not started (or already stopped and never restarted) is a usage error.","triggerScenarios":"Constructing _BashSession and calling stop() without start(); calling stop() twice after an exception in start(); cleanup paths (finally blocks) that stop a session whose start() threw.","commonSituations":"try/finally cleanup where start() failed and finally still calls stop(); generic teardown code iterating over sessions that may be unstarted.","solutions":["Only call stop() after a successful start(): set a flag or assign the session only after await start() completes.","In cleanup code, guard with the same condition the class uses: 'if session._started: session.stop()' — better, wrap stop() in try/except ToolError and ignore the not-started case.","Structure setup as 'session = None; try: session = _BashSession(); await session.start() ... finally: if session ... stop()' so an unstarted session is never stopped."],"exampleFix":"# before\nsession = _BashSession()\ntry:\n    await session.start()\n    ...\nfinally:\n    session.stop()  # ToolError if start() raised\n\n# after\ntry:\n    session = _BashSession()\n    await session.start()\n    ...\nfinally:\n    if session is not None and session._started:\n        session.stop()","handlingStrategy":"validation","validationCode":"if session._started:\n    session.stop()","typeGuard":"def is_stoppable(s: _BashSession) -> bool:\n    return bool(s._started) and s._process is not None and s._process.returncode is None","tryCatchPattern":"try:\n    session.stop()\nexcept ToolError as e:\n    if 'Session has not started.' not in str(e):\n        raise  # ignore the not-started case during cleanup","preventionTips":["Only reference the session after start() succeeds.","In finally blocks, guard stop() with the started flag.","Treat stop-before-start as a wiring bug; fix the ordering."],"tags":["bash","lifecycle","tool-error"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}