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

  1. Keep sandbox_config set for the logger's whole lifetime — do not mutate it after containers are created
  2. If configuring per-request, create a fresh CodeInterpreterInterceptionLogger instead of mutating one
  3. 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

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


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)