{"record":{"id":"f8e5f33c0db1cd71","repo":"BerriAI/litellm","slug":"opensandbox-did-not-return-an-execd-endpoint-for","errorCode":null,"errorMessage":"OpenSandbox did not return an execd endpoint for {sandbox_id}","messagePattern":"OpenSandbox did not return an execd endpoint for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/opensandbox/sandbox/transformation.py","lineNumber":320,"sourceCode":"        *,\n        sandbox_id: str,\n        api_base: str,\n        headers: dict[str, str],\n        use_server_proxy: bool,\n        client: AsyncHTTPHandler | None,\n    ) -> tuple[str, dict[str, str]]:\n        response: Final = cast(\n            httpx.Response,\n            await self._http(client).get(\n                url=f\"{api_base}/sandboxes/{sandbox_id}/endpoints/{OPEN_SANDBOX_EXECD_PORT}\",\n                headers=headers,\n                params={\"use_server_proxy\": use_server_proxy},\n            ),\n        )\n        data: Final = response.json()\n        endpoint: Final = data.get(\"endpoint\")\n        if not endpoint:\n            raise ValueError(f\"OpenSandbox did not return an execd endpoint for {sandbox_id}\")\n        return str(endpoint), self._as_str_dict(data.get(\"headers\"))\n\n    async def _post_code(\n        self,\n        *,\n        url: str,\n        headers: dict[str, str],\n        body: dict[str, object],\n        client: AsyncHTTPHandler | None,\n    ) -> list[str]:\n        timeout: Final = httpx.Timeout(connect=30.0, read=None, write=30.0, pool=None)\n        response: Final = cast(\n            httpx.Response,\n            await self._http(client).post(\n                url=url,\n                headers=headers,\n                timeout=timeout,\n                json=body,","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/opensandbox/sandbox/transformation.py#L302-L338","documentation":"LiteLLM fetches the execd endpoint with GET /sandboxes/{id}/endpoints/{OPEN_SANDBOX_EXECD_PORT} and reads the 'endpoint' field from the JSON body. If that field is missing, null, or empty, it raises ValueError because it cannot construct the URL to talk to the sandbox. The HTTP call itself succeeded - the payload is just unusable.","triggerScenarios":"The control plane returns HTTP 200 with an error object or partial record instead of an endpoint field; querying a port the sandbox never opened; schema drift in the OpenSandbox endpoints API returning a renamed field.","commonSituations":"Provider API changes renaming 'endpoint'; regional endpoints returning empty records during incidents; racing against sandbox teardown so the record exists but is empty.","solutions":["Manually GET the endpoints URL with the same lifecycle headers to inspect the actual payload","Confirm the execd port is correct and the sandbox image exposes it","Retry - empty endpoint records are often transient right after registration","Recreate the sandbox if the record stays empty"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Catch ValueError with 'did not return an execd endpoint' and retry the endpoint fetch after a short delay - empty records right after registration are often transient; if it persists, delete and recreate the sandbox.","preventionTips":["Health-check the endpoints API manually when integrating a custom sandbox image","Treat a missing endpoint field as a distinct failure class from HTTP errors in monitoring","Keep sandbox creation idempotent so recreation is cheap"],"tags":["opensandbox","endpoint","missing-field","response-parsing","litellm"],"backgroundTag":"missing-response-field","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}