microsoft/autogen · error · RuntimeError
Executor must be started before executing cells
Error message
Executor must be started before executing cells
What it means
Raised by JupyterCodeExecutor._execute_cell when self._client is falsy, meaning the executor was never started. The executor must be running (start() called, or entered via 'async with') before execute_code_blocks is invoked.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/code_executors/jupyter/_jupyter_code_executor.py:246
path = self._save_image(content)
output_files.append(path)
case "image/jpeg":
# TODO: Should this also be encoded? Images are encoded as both png and jpg
pass
case "text/html":
path = self._save_html(content)
output_files.append(path)
case _:
outputs.append(json.dumps(content))
case _:
pass
return JupyterCodeResult(exit_code=exit_code, output="\n".join(outputs), output_files=output_files)
async def _execute_cell(self, cell: NotebookNode) -> NotebookNode:
# Temporary push cell to nb as async_execute_cell expects it. But then we want to remove it again as cells can take up significant amount of memory (especially with images)
if not self._client:
raise RuntimeError("Executor must be started before executing cells")
self._client.nb.cells.append(cell)
output = await self._client.async_execute_cell(
cell,
cell_index=0,
)
self._client.nb.cells.pop()
return output
def _save_image(self, image_data_base64: str) -> Path:
"""Save image data to a file."""
image_data = base64.b64decode(image_data_base64)
path = self._output_dir / f"{uuid.uuid4().hex}.png"
path.write_bytes(image_data)
return path.absolute()
def _save_html(self, html_data: str) -> Path:
"""Save HTML data to a file."""
path = self._output_dir / f"{uuid.uuid4().hex}.html"View on GitHub (pinned to 027ecf0a37)
Solutions
- Call await executor.start() before executing, and prefer the context-manager form 'async with JupyterCodeExecutor() as e: ...'.
- If used inside an agent runtime, attach the executor before the first code-execution turn so the runtime starts it.
- Do not reuse an executor after stop(); create and start a new one.
Example fix
# before
executor = JupyterCodeExecutor()
result = await executor.execute_code_blocks([CodeBlock(code="1+1", language="python")], CancellationToken())
# after
async with JupyterCodeExecutor() as executor:
result = await executor.execute_code_blocks([CodeBlock(code="1+1", language="python")], CancellationToken()) Defensive patterns
Strategy: validation
Validate before calling
async def execute(executor, blocks, token):
if not getattr(executor, "_started", False):
await executor.start()
return await executor.execute_code_blocks(blocks, token) Type guard
from autogen_ext.code_executors.jupyter import JupyterCodeExecutor
def is_started(executor: JupyterCodeExecutor) -> bool:
return getattr(executor, "_started", False) Try / catch
try:
await executor.execute_code_blocks(blocks, token)
except RuntimeError as e:
if "must be started" in str(e):
await executor.start()
result = await executor.execute_code_blocks(blocks, token)
else:
raise Prevention
- Prefer 'async with JupyterCodeExecutor() as executor:' so lifecycle is automatic.
- Attach executors to the runtime before the first code-execution turn.
- Never share one executor across sequential runs without restarting it.
When it happens
Trigger: Calling execute_code_blocks() (or any code-execution path) on a JupyterCodeExecutor instance that did not go through await executor.start() or 'async with executor:'; using an executor after stop(); relying on an agent runtime that does not auto-start executors.
Common situations: Borrowing the executor for manual calls outside a runtime, forgetting 'async with' in scripts, calling execute before the runtime registered the executor (ordering bugs in custom agent loops), reusing a stopped executor.
Related errors
- Timeout must be greater than or equal to 1.
- Kernel {self._kernel_name} is not installed.
- Timeout must be greater than or equal to 1.
- Kernel is not running
- Installing directory is not set
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/91190ab7cfda74ba.
Report an issue: GitHub.