BerriAI/litellm · error · ValueError
CodeInterpreterInterception: no sandbox available to run…
Error message
CodeInterpreterInterception: no sandbox available to run code.
What it means
_run_code() dispatches to sandbox_config.arun_code when sandbox_config is set; otherwise it needs the SandboxToolParams that _create_container() captured when the container was created (it holds provider/api_key). The ValueError fires when sandbox_config is None AND params is None — a state that normally cannot occur from _create_container(), so it indicates the sandbox_config was cleared or the container/params pairing was broken between creation and execution (e.g. mutating the logger config mid-session or a custom subclass bypassing the factory).
Solutions
- Keep sandbox_config set for the logger's whole lifetime — do not mutate it after containers are created
- If configuring per-request, create a fresh CodeInterpreterInterceptionLogger instead of mutating one
- If you wrap _create_container/_run_code, always pass through the (container, params) pair unchanged
Example fix
# before container, params = await logger._create_container() logger.sandbox_config = None # cleared mid-session await logger._run_code(container, params, code) # params is None when created via config -> ValueError # after container, params = await logger._create_container() await logger._run_code(container, params, code) # config and params kept consistent
Defensive patterns
Strategy: validation
Validate before calling
if logger.sandbox_config is None and params is None:
raise RuntimeError('cannot run code: sandbox config was cleared after container creation')
result = await logger._run_code(container, params, code) Type guard
def can_run_code(logger, params) -> bool:
return logger.sandbox_config is not None or params is not None Try / catch
except ValueError as e:
if 'no sandbox available to run code' in str(e):
recreate container via _create_container() with a consistent config, then retry once
else:
raise Prevention
- Treat CodeInterpreterInterceptionLogger config as immutable after construction
- Always keep the (container, params) pair from _create_container together
- Create a fresh logger per distinct sandbox configuration
When it happens
Trigger: Setting logger.sandbox_config = None after containers were created; a subclass or cache path that produces a container without SandboxToolParams; restoring or hand-crafting a ContainerHandle and calling _run_code directly with params=None.
Common situations: Hot-reloading or reconfiguring the interception callback while cached containers exist; custom integrations wrapping the handler and dropping the params tuple element.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- CodeInterpreterInterception: no sandbox available. Provide…
- OpenSandbox execd endpoint for
- OpenSandbox sandbox entered
- OpenSandbox sandbox was not Running within seconds
- 400
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/7fc82da0f5316464.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/code_interpreter_interception/handler.py:758
raise ValueError(
"CodeInterpreterInterception: no sandbox available. Provide a "
"sandbox_config or configure a sandbox tool resolvable via "
"sandbox_tool_name."
)
container: Final = await litellm.acreate_sandbox(
provider=params["sandbox_provider"],
api_key=params.get("api_key"),
api_base=params.get("api_base"),
)
return container, params
async def _run_code(
self, container: ContainerHandle, params: SandboxToolParams | None, code: str
) -> CodeExecutionResult:
if self.sandbox_config is not None:
return await self.sandbox_config.arun_code(container=container, code=code)
if params is None:
raise ValueError("CodeInterpreterInterception: no sandbox available to run code.")
return await litellm.arun_code(
provider=params["sandbox_provider"],
container=container,
code=code,
api_key=params.get("api_key"),
)
async def _delete_container(self, container: ContainerHandle, params: SandboxToolParams | None) -> None:
try:
if self.sandbox_config is not None:
await self.sandbox_config.adelete_sandbox(container=container)
return
if params is None:
return
await litellm.adelete_sandbox(
provider=params["sandbox_provider"],
container=container,
api_key=params.get("api_key"),View on GitHub (pinned to 77b7c6c40c)