Skip to content

GkeCodeExecutor sandbox mode raises TypeError with k8s-agent-sandbox >= 0.3 #7716

Description

@nirajan1111

🔴 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:

  1. pip install "google-adk[extensions]" (resolves k8s-agent-sandbox==1.0.8)
  2. Create GkeCodeExecutor(executor_type="sandbox") with any kubeconfig
  3. 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

  1. added a commit that references this issue on Oct 25, 2026
    5d18c29
  2. surajksharma07 commented on Oct 26, 2026

    @surajksharma07
    Collaborator

    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.

  3. nirajan1111 commented on Oct 26, 2026

    @nirajan1111
    Author

    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-router v1.0.8, SandboxWarmPool python-sandbox-pool. For gateway mode: cloud-provider-kind (GatewayClass cloud-provider-kind), a Gateway kind-gateway in default, and an HTTPRoute to sandbox-router-svc. Each run executes one passing script and one that writes to stderr and exits 3.

    mode k8s-agent-sandbox success case failure case claims left
    default tunnel 1.0.8 exit 0, stdout ok exit 3, stderr ok 0
    default tunnel 0.5.0 exit 0, stdout ok exit 3, stderr ok 0
    sandbox_gateway_name="kind-gateway" 1.0.8 exit 0, stdout ok exit 3, stderr ok 0
    sandbox_gateway_name="kind-gateway" 0.5.0 exit 0, stdout ok exit 3, stderr ok 0

    Gateway mode, 1.0.8:

    google-adk 2.13.0 | k8s-agent-sandbox 1.0.8 | mode: gateway (kind-gateway)
      sdk: Waiting for Gateway 'kind-gateway' in namespace 'default'...
      sdk: Gateway ready. IP: 172.21.0.3
    [success] exit_code=0 stdout='hello from python-sandbox-pool-9k64d\n45\n' stderr=''
    [failure] exit_code=3 stdout='' stderr='to stderr\n'
    

    Gateway mode, 0.5.0:

    google-adk 2.13.0 | k8s-agent-sandbox 0.5.0 | mode: gateway (kind-gateway)
    [success] exit_code=0 stdout='hello from python-sandbox-pool-fs7gq\n45\n' stderr=''
    [failure] exit_code=3 stdout='' stderr='to stderr\n'
    

    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:

    • Gateway mode ran from a container on the kind Docker network, because the Gateway's address isn't reachable from the macOS host.
    • The router's example NetworkPolicy only admits in-cluster pods on 8080, so for this test I added a policy allowing the kind subnet.
    • GkeCodeExecutor doesn't expose gateway_namespace, so the Gateway has to be in default, the SDK's default. That limitation predates this PR, and I left it out of scope.
  4. surajksharma07 commented on Oct 27, 2026

    @surajksharma07
    Collaborator

    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.

  5. added
    agent engine[Component] This issue is related to Vertex AI Agent Engine
    on Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

agent engine[Component] This issue is related to Vertex AI Agent Engine

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions