Repository navigation
GkeCodeExecutor sandbox mode raises TypeError with k8s-agent-sandbox >= 0.3 #7716
Description
🔴 Required Information
Describe the Bug:
GkeCodeExecutor(executor_type="sandbox") raises TypeError on every call with any current k8s-agent-sandbox release. _execute_in_sandbox still uses the 0.1.x/0.2.x client API (SandboxClient(template_name=..., gateway_name=..., namespace=...), sandbox.write, sandbox.run). Since 0.3 the client takes a connection_config, and since 0.5 sandboxes are claimed from a SandboxWarmPool with create_sandbox(warmpool=...). ADK requires k8s-agent-sandbox>=0.1.1.post3 with no upper bound, so a fresh pip install google-adk[extensions] resolves 1.0.8 and sandbox mode cannot work.
Steps to Reproduce:
pip install "google-adk[extensions]"(resolvesk8s-agent-sandbox==1.0.8)- Create
GkeCodeExecutor(executor_type="sandbox")with any kubeconfig - Call
execute_code(...)
Expected Behavior:
The code runs in a sandbox claimed from the cluster's warm pool.
Observed Behavior:
TypeError: SandboxClient.__init__() got an unexpected keyword argument 'template_name'
The error is raised before any request reaches the cluster.
Environment Details:
- ADK Library Version (pip show google-adk): 2.13.0 (main at 12c7bed)
- Desktop OS: macOS
- Python Version (python -V): 3.11
Model Information:
- Are you using LiteLLM: N/A (no model involved)
- Which model is being used: N/A
🟡 Optional Information
Regression:
It worked only while k8s-agent-sandbox 0.1.x/0.2.x was the latest release. mypy on main already reports it: Unexpected keyword argument "template_name" for "SandboxClient". The unit tests mock SandboxClient without a spec, so they don't catch it.
Additional Context:
Tracked upstream as kubernetes-sigs/agent-sandbox#1038. SandboxClient signature by release:
| k8s-agent-sandbox | SandboxClient(...) |
creates a sandbox with |
|---|---|---|
| 0.1.1.post3, 0.2.1 | template_name, namespace, gateway_name, ... |
the client itself |
| 0.3.x, 0.4.x | connection_config, ... |
create_sandbox(template=...) |
| 0.5.0 – 1.0.8 | connection_config, ... |
create_sandbox(warmpool=...) |
Minimal Reproduction Code:
from unittest import mock
from google.adk.code_executors import gke_code_executor as gke
from google.adk.code_executors.code_execution_utils import CodeExecutionInput
with mock.patch.object(gke.config, "load_incluster_config"), \
mock.patch.object(gke.client, "BatchV1Api"), \
mock.patch.object(gke.client, "CoreV1Api"):
executor = gke.GkeCodeExecutor(executor_type="sandbox")
executor.execute_code(mock.MagicMock(), CodeExecutionInput(code='print("hi")'))How often has this issue occurred?:
- Always (100%)
Activity
fix(code_executors): use the current k8s-agent-sandbox API in GkeCode…
surajksharma07 commentedon Oct 26, 2026
Reproduced the same TypeError on main (2.13.0) with k8s-agent-sandbox 1.0.8 @nirajan1111 so the context here is complete.
Tried a similar approach as a workaround (SandboxClient(connection_config=...), create_sandbox(warmpool=...), files.write/commands.run, terminate() in finally) and it looks good with an autospec’d client.
Could you double-check it on your kind cluster with sandbox_gateway_name set as well as the default tunnel and on the 0.5.x floor just to be sure nothing is missed?
Once that’s confirmed working end to end we can move ahead with the review on #7720.
nirajan1111 commentedon Oct 26, 2026
Thanks for reproducing it. I reran the E2E with the PR branch (5d18c29) in both connection modes, on the 0.5.0 floor and on 1.0.8.
Setup: kind, agent-sandbox v1.0.8 (controller + extensions),
sandbox-routerv1.0.8,SandboxWarmPoolpython-sandbox-pool. For gateway mode:cloud-provider-kind(GatewayClasscloud-provider-kind), aGatewaykind-gatewayindefault, and anHTTPRoutetosandbox-router-svc. Each run executes one passing script and one that writes to stderr and exits 3.sandbox_gateway_name="kind-gateway"sandbox_gateway_name="kind-gateway"Gateway mode, 1.0.8:
Gateway mode, 0.5.0:
To confirm which path each run took (0.5.0 doesn't log it), I checked the router access logs: the tunnel runs arrived from
127.0.0.1(port-forward) and the gateway runs from the Gateway's Envoy. Each mode logged 8 requests, which matches 2 runs × 2 cases × (write + run).Notes:
kindDocker network, because the Gateway's address isn't reachable from the macOS host.GkeCodeExecutordoesn't exposegateway_namespace, so the Gateway has to be indefault, the SDK's default. That limitation predates this PR, and I left it out of scope.surajksharma07 commentedon Oct 27, 2026
That’s a really thorough run @nirajan1111. The router logs make it clear that both the tunnel and gateway paths were actually used on 0.5.0 and 1.0.8.
Compared #7720 against the 1.0.8 SDK source and the calls match: create_sandbox(warmpool, namespace) and terminate() closes the tunnel and deletes the claim. That lines up with the 0 leftover claims you saw. Your autospec’d tests also fail on current main as expected (9 failures).
One small optional nit: if terminate() itself fails in the finally block (for example the claim DELETE errors) it hides an otherwise good result so maybe log that error instead of letting it escape.
Agreed on keeping gateway_namespace out of scope here, it can be a small follow-up. From the triage side this looks ready for @xuanyang15’s review once the workflows are approved.