BerriAI/litellm · error · ValueError

CodeInterpreterInterception: no sandbox available. Provide…

Error message

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

What it means

CodeInterpreterInterception executes model-generated code in a sandbox. _create_container() first uses self.sandbox_config if given; otherwise it resolves a sandbox provider via _resolve_sandbox_tool(self.sandbox_tool_name), which returns None when sandbox_tool_name is None, when litellm.sandbox.sandbox_tools cannot be imported, or when resolve_sandbox_tool finds no registered tool with that name. With both paths empty it raises this ValueError so code never runs locally.

Solutions

  1. Pass sandbox_config to CodeInterpreterInterception(...) (a provider sandbox config object implementing acreate_sandbox/arun_code/adelete_sandbox)
  2. Or set sandbox_tool_name to a registered sandbox tool name so _resolve_sandbox_tool succeeds, and provide that provider's credentials
  3. Verify the config block actually reaches the logger: code_interpreter_interception_params with sandbox_tool_name under litellm_settings
  4. Check the provider's API key env vars are set so the tool is resolvable at runtime

Example fix

# before
CodeInterpreterInterceptionLogger()  # no sandbox_config, no sandbox_tool_name
# ValueError: no sandbox available. Provide a sandbox_config or configure a sandbox tool...

# after
from litellm.integrations.code_interpreter_interception.handler import CodeInterpreterInterceptionLogger
logger = CodeInterpreterInterceptionLogger(
    sandbox_config=MyProviderSandboxConfig(api_key=...),  # or sandbox_tool_name='my_daytona_tool'
)
Defensive patterns

Strategy: validation

Validate before calling

logger = CodeInterpreterInterceptionLogger(sandbox_tool_name=name)
if logger.sandbox_config is None and _resolve_sandbox_tool(name) is None:
    raise RuntimeError('configure sandbox_config or a registered sandbox_tool_name before enabling interception')

Type guard

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

Try / catch

try:
    container, params = await logger._create_container()
except ValueError as e:
    if 'no sandbox available' in str(e):
        # fail with config guidance instead of retrying
        raise RuntimeError('code interception needs sandbox_config or sandbox_tool_name') from e
    raise

Prevention

When it happens

Trigger: Enabling code_interpreter_interception without sandbox_config and without sandbox_tool_name (both default to None); setting sandbox_tool_name to a name that has no registered sandbox tool (no matching provider config/credentials); sandbox support module unavailable in the installed litellm build.

Common situations: Turning on the code-interpreter interception callback in the proxy config but forgetting the sandbox block; passing sandbox_tool_name with a typo or before registering the tool; environments where optional sandbox dependencies are not installed.

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/9ee44671bcf0ebab. Report an issue: GitHub.

Appendix: 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 77b7c6c40c)