Skip to content

Conversation

@mlingner
Copy link
Contributor

@mlingner mlingner commented Jan 29, 2026

Summary

Attempts to fix #82

I ran into this issue while building a TypeScript version of the weather bot tutorial. When a sub-agent completes and the model tries to return control to the root agent, it fails because the sub-agent's rootAgent property points to itself rather than the actual root.

Thanks to @santosflores for investigating this in #83, and to @ScottMansfield for pointing out that the Python SDK doesn't need recursive updates. It uses a computed property that walks up the parent chain each time.

This PR takes that same approach: replacing the cached rootAgent property with a getter, matching how the Python SDK handles it:

@property
def root_agent(self) -> BaseAgent:
    root_agent = self
    while root_agent.parent_agent is not None:
        root_agent = root_agent.parent_agent
    return root_agent

Changes

  • Removed readonly rootAgent: BaseAgent property assignment in constructor
  • Added get rootAgent(): BaseAgent getter that computes the root by walking up the parent chain

Reproduction

Minimal example:

import { FunctionTool, LlmAgent } from '@google/adk';
import { z } from 'zod';

const tellJoke = new FunctionTool({
    name: 'tell_joke',
    description: 'Tells a joke',
    parameters: z.object({}),
    execute: () => ({ joke: 'Why do programmers prefer dark mode? Because light attracts bugs!' }),
});

const subAgent = new LlmAgent({
    name: 'sub_agent',
    model: 'gemini-2.0-flash',
    description: 'Handles greetings',
    instruction: 'Greet the user.',
});

export const rootAgent = new LlmAgent({
    name: 'root_agent',
    model: 'gemini-2.0-flash',
    description: 'Main agent',
    instruction: 'Delegate greetings to sub_agent. For joke requests, use the tell_joke tool.',
    tools: [tellJoke],
    subAgents: [subAgent]
});

subAgent is created first, so its constructor sets rootAgent = this (pointing to itself). When it's later added to rootAgent via subAgents, the cached value is never updated.

Before fix:

[user]: hi
[sub_agent]: Hello!
[user]: tell me a joke
Error: Agent root_agent not found in the agent tree.

After fix:

[user]: hi
[sub_agent]: Hello!
[user]: tell me a joke
[root_agent]: Why do programmers prefer dark mode? Because light attracts bugs!

Test Plan

  • Run unit tests in core/test/agents/base_agent_test.ts to verify sub-agents correctly resolve their rootAgent
  • Test locally using the repro steps above

@google-cla
Copy link

google-cla bot commented Jan 29, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Collaborator

@kalenkevich kalenkevich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@santosflores
Copy link

Thanks a lot. I think solving this bug will result on the adk webserver in TS to finally display data inside the Trace tab. I'll try it once you release.

Attaching an image of the current behavior.

Screenshot 2026-01-28 at 6 16 27 PM

@mlingner mlingner force-pushed the fix/issue-82-root-agent-getter branch from 5d69f7d to a6e470c Compare January 30, 2026 08:33
@mlingner
Copy link
Contributor Author

Squashed into a single commit and fixed Prettier formatting in the test file for CI. :)

@kalenkevich kalenkevich merged commit 23b1d7f into google:main Jan 30, 2026
6 checks passed
@kalenkevich kalenkevich mentioned this pull request Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent execution crashes when subagent attempts to transfer control back to an orchestrator

3 participants