BerriAI/litellm · error · ValueError

CodeInterpreterInterception: no sandbox available. Provide a

Error message

CodeInterpreterInterception: no sandbox available. Provide a sandbox_config or configure a sandbox tool resolvable via sandbox_tool_name.

What it means

ValueError from CodeInterpreterInterception._create_container: the handler can spin up a sandbox either from an explicit sandbox_config or by resolving sandbox provider credentials from the LiteLLM proxy's configured tools via sandbox_tool_name. When sandbox_config is None AND _resolve_sandbox_tool(sandbox_tool_name) returns None (no tool with that name, or the named tool has no sandbox_provider), container creation refuses to continue.

Source

Thrown at litellm/integrations/code_interpreter_interception/handler.py:740

                await self._evict_lru_session_if_over_cap(identity)
            self._container_cache[cache_key] = (container, params, time.time(), identity)
        return container, params

    async def _evict_lru_session_if_over_cap(self, identity: str) -> None:
        identity_entries: Final = [(k, v) for k, v in self._container_cache.items() if v[3] == identity]
        if len(identity_entries) < _SESSION_SCOPED_PER_IDENTITY_CAP:
            return
        lru_key, lru_entry = min(identity_entries, key=lambda item: item[1][2])
        self._container_cache.pop(lru_key, None)
        await self._delete_container(container=lru_entry[0], params=lru_entry[1])

    async def _create_container(self) -> tuple[ContainerHandle, SandboxToolParams | None]:
        if self.sandbox_config is not None:
            return await self.sandbox_config.acreate_sandbox(), None

        params: Final = _resolve_sandbox_tool(self.sandbox_tool_name)
        if params is None:
            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.")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Configure a sandbox provider tool in the proxy (e.g. an e2b tool with sandbox_provider and api_key) and point sandbox_tool_name at its exact name
  2. Or pass an explicit sandbox_config object when constructing the handler
  3. Verify the tool name matches character-for-character (case-sensitive) the name in your tools config
  4. Check the tool's metadata actually includes sandbox_provider and a valid api_key

Example fix

# before
handler = CodeInterpreterInterception()  # no sandbox_config, no matching tool

# after
handler = CodeInterpreterInterception(
    sandbox_tool_name="e2b-sandbox",  # must match a configured tool with sandbox_provider metadata
)
# tools config:
# tools:
#   - name: e2b-sandbox
#     metadata:
#       sandbox_provider: e2b
#       api_key: os.environ/E2B_API_KEY
Defensive patterns

Strategy: validation

Validate before calling

def sandbox_available(handler) -> bool:
    if handler.sandbox_config is not None:
        return True
    from litellm.integrations.code_interpreter_interception.handler import _resolve_sandbox_tool
    return _resolve_sandbox_tool(handler.sandbox_tool_name) is not None

if not sandbox_available(handler):
    raise RuntimeError("Configure sandbox_config or a sandbox tool before enabling code interception")

Type guard

def can_create_sandbox(handler) -> bool:
    """True when either sandbox_config or a resolvable sandbox tool exists."""
    return handler.sandbox_config is not None or (
        getattr(handler, "sandbox_tool_name", None) is not None
        and _resolve_sandbox_tool(handler.sandbox_tool_name) is not None
    )

Try / catch

try:
    container, params = await handler._create_container()
except ValueError as e:
    if "no sandbox available" in str(e):
        degrade_to_no_code_execution()
    else:
        raise

Prevention

When it happens

Trigger: Enabling the code_interpreter_interception callback with neither sandbox_config set on the handler nor a matching litellm tool entry whose metadata contains sandbox_provider/api_key; sandbox_tool_name spelled differently from the tool name in config; the tool exists but lacks sandbox provider credentials.

Common situations: Adding the code-intercept feature to a proxy that has no e2b/daytona/modal sandbox tool configured; renaming a tool in config.yaml without updating sandbox_tool_name; local dev setups without any sandbox provider account.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/9ee44671bcf0ebab. Report an issue: GitHub.