Skip to content

[Live/bidi] transfer_to_agent crashes with 1011 on Agent Engine — sub_agents delegation not supported on bidi_stream_query #5195

@smwitkowski

Description

@smwitkowski

Required Information

Describe the Bug

When using bidi_stream_query() on Agent Engine, any agent that registers sub-agents via sub_agents=[...] crashes with a 1011 (internal error) WebSocket close when the model calls the built-in transfer_to_agent function. The sub-agent never executes. The session is terminated immediately.

Crash rate: 100% when transfer_to_agent fires (10/10 trials in isolated reproduction).

This is specific to the bidi/live path on Agent Engine. The same agent with the same sub-agents works correctly via Runner.run_async locally (10/10 PASS — sub-agent delegation succeeds, response is produced).

Workaround: Wrapping the sub-agent in AgentTool(agent) instead of registering it via sub_agents=[] avoids the crash. AgentTool registers a regular function call (not transfer_to_agent) that works on the bidi path.

Steps to Reproduce

  1. Create subagent_crash/agent.py:
from google.adk.agents import Agent
from google.adk.models import Gemini
from google.genai.types import GenerateContentConfig

faq_agent = Agent(
    name="faq_agent",
    description="Answers all user questions",
    model=Gemini(model="gemini-2.5-flash"),
    instruction="Answer the user's question concisely in 1-2 sentences.",
    tools=[],
)

root_agent = Agent(
    model=Gemini(model="gemini-live-2.5-flash-native-audio"),
    name="root_agent",
    instruction=(
        "You are a routing agent. You MUST delegate ALL user messages to faq_agent "
        "using the transfer_to_agent function. "
        "NEVER answer any question yourself. NEVER respond directly. "
        "For EVERY single user message, immediately call transfer_to_agent with "
        "agent_name='faq_agent'. No exceptions."
    ),
    sub_agents=[faq_agent],
    tools=[],
    generate_content_config=GenerateContentConfig(temperature=0.0),
)
  1. Create subagent_crash/agent_engine_app.py:
from vertexai.preview.reasoning_engines.templates.adk import AdkApp
from subagent_crash.agent import root_agent

class AgentEngineApp(AdkApp):
    def register_operations(self):
        operations = super().register_operations()
        operations["bidi_stream"] = ["bidi_stream_query"]
        return operations

agent_engine = AgentEngineApp(agent=root_agent)
  1. Deploy to Agent Engine, connect via bidi, and send any message:
import asyncio
import vertexai

async def test():
    client = vertexai.Client(project="YOUR_PROJECT", location="us-central1")
    async with client.aio.live.agent_engines.connect(
        agent_engine="projects/.../reasoningEngines/..."
    ) as session:
        await session.send(query_input={"user_id": "test"})
        await session.send(query_input={
            "content": {"role": "user", "parts": [{"text": "Hello"}]}
        })
        while True:
            event = await asyncio.wait_for(session.receive(), timeout=15)
            print(event)

asyncio.run(test())

Expected Behavior

The model calls transfer_to_agent(agent_name="faq_agent"), ADK transfers control to faq_agent, the sub-agent responds, and the response is streamed back via the bidi session.

Actual Behavior

Event 1: function_call: transfer_to_agent(agent_name="faq_agent")
Event 2: function_response: transfer_to_agent → result: null
         → ConnectionClosedError: received 1011 (internal error)
         → "Reasoning Engine Execution failed"

The WebSocket closes immediately after the transfer_to_agent function response. Only 4 events are produced. No content is delivered to the user.

Key Distinction: sub_agents vs AgentTool

This crash is specific to the sub_agents=[] parameter, which registers the built-in transfer_to_agent function. Wrapping the same agent in AgentTool() and placing it in tools=[] registers a regular function call and does not crash:

# CRASHES on bidi — uses transfer_to_agent internally
root_agent = Agent(
    sub_agents=[faq_agent],
    ...
)

# WORKS on bidi — uses regular function call
from google.adk.tools import AgentTool
root_agent = Agent(
    tools=[AgentTool(faq_agent)],
    ...
)

Both patterns work identically via Runner.run_async locally. The crash is only on the Agent Engine bidi path.

Local Baseline

Same agent tested locally via Runner.run_async with gemini-2.5-flash: 10/10 PASS. transfer_to_agent is called, the sub-agent runs, a response is produced. The crash is specific to Agent Engine's bidi_stream_query.

Environment

  • google-adk==1.28.1
  • google-cloud-aiplatform==1.145.0
  • Model: gemini-live-2.5-flash-native-audio (root), gemini-2.5-flash (sub-agent)
  • Path: bidi_stream_query on Vertex AI Agent Engine
  • Python 3.10
  • Region: us-central1

Related Issues

Metadata

Metadata

Assignees

Labels

live[Component] This issue is related to live, voice and video chat

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions