{"record":{"id":"9ee44671bcf0ebab","repo":"BerriAI/litellm","slug":"codeinterpreterinterception-no-sandbox-available","errorCode":null,"errorMessage":"CodeInterpreterInterception: no sandbox available. Provide a sandbox_config or configure a sandbox tool resolvable via sandbox_tool_name.","messagePattern":"CodeInterpreterInterception: no sandbox available\\. Provide a sandbox_config or configure a sandbox tool resolvable via sandbox_tool_name\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/code_interpreter_interception/handler.py","lineNumber":740,"sourceCode":"                await self._evict_lru_session_if_over_cap(identity)\n            self._container_cache[cache_key] = (container, params, time.time(), identity)\n        return container, params\n\n    async def _evict_lru_session_if_over_cap(self, identity: str) -> None:\n        identity_entries: Final = [(k, v) for k, v in self._container_cache.items() if v[3] == identity]\n        if len(identity_entries) < _SESSION_SCOPED_PER_IDENTITY_CAP:\n            return\n        lru_key, lru_entry = min(identity_entries, key=lambda item: item[1][2])\n        self._container_cache.pop(lru_key, None)\n        await self._delete_container(container=lru_entry[0], params=lru_entry[1])\n\n    async def _create_container(self) -> tuple[ContainerHandle, SandboxToolParams | None]:\n        if self.sandbox_config is not None:\n            return await self.sandbox_config.acreate_sandbox(), None\n\n        params: Final = _resolve_sandbox_tool(self.sandbox_tool_name)\n        if params is None:\n            raise ValueError(\n                \"CodeInterpreterInterception: no sandbox available. Provide a \"\n                \"sandbox_config or configure a sandbox tool resolvable via \"\n                \"sandbox_tool_name.\"\n            )\n        container: Final = await litellm.acreate_sandbox(\n            provider=params[\"sandbox_provider\"],\n            api_key=params.get(\"api_key\"),\n            api_base=params.get(\"api_base\"),\n        )\n        return container, params\n\n    async def _run_code(\n        self, container: ContainerHandle, params: SandboxToolParams | None, code: str\n    ) -> CodeExecutionResult:\n        if self.sandbox_config is not None:\n            return await self.sandbox_config.arun_code(container=container, code=code)\n        if params is None:\n            raise ValueError(\"CodeInterpreterInterception: no sandbox available to run code.\")","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/code_interpreter_interception/handler.py#L722-L758","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","Or pass an explicit sandbox_config object when constructing the handler","Verify the tool name matches character-for-character (case-sensitive) the name in your tools config","Check the tool's metadata actually includes sandbox_provider and a valid api_key"],"exampleFix":"# before\nhandler = CodeInterpreterInterception()  # no sandbox_config, no matching tool\n\n# after\nhandler = CodeInterpreterInterception(\n    sandbox_tool_name=\"e2b-sandbox\",  # must match a configured tool with sandbox_provider metadata\n)\n# tools config:\n# tools:\n#   - name: e2b-sandbox\n#     metadata:\n#       sandbox_provider: e2b\n#       api_key: os.environ/E2B_API_KEY","handlingStrategy":"validation","validationCode":"def sandbox_available(handler) -> bool:\n    if handler.sandbox_config is not None:\n        return True\n    from litellm.integrations.code_interpreter_interception.handler import _resolve_sandbox_tool\n    return _resolve_sandbox_tool(handler.sandbox_tool_name) is not None\n\nif not sandbox_available(handler):\n    raise RuntimeError(\"Configure sandbox_config or a sandbox tool before enabling code interception\")","typeGuard":"def can_create_sandbox(handler) -> bool:\n    \"\"\"True when either sandbox_config or a resolvable sandbox tool exists.\"\"\"\n    return handler.sandbox_config is not None or (\n        getattr(handler, \"sandbox_tool_name\", None) is not None\n        and _resolve_sandbox_tool(handler.sandbox_tool_name) is not None\n    )","tryCatchPattern":"try:\n    container, params = await handler._create_container()\nexcept ValueError as e:\n    if \"no sandbox available\" in str(e):\n        degrade_to_no_code_execution()\n    else:\n        raise","preventionTips":["Validate sandbox configuration at handler construction, not at first code run","Keep sandbox_tool_name in lockstep with the tool name in proxy config","Include sandbox provider credentials in the tool metadata, not just the name"],"tags":["code-interpreter","sandbox","configuration","tools"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}