Skip to content

fix(core): isolate subagent thread context#26449

Open
akh64bit wants to merge 4 commits intomainfrom
fix/subagent-isolation-25533
Open

fix(core): isolate subagent thread context#26449
akh64bit wants to merge 4 commits intomainfrom
fix/subagent-isolation-25533

Conversation

@akh64bit
Copy link
Copy Markdown
Contributor

@akh64bit akh64bit commented May 4, 2026

Isolate subagent thread context by incorporating parentCallId into agentId.
This prevents parallel subagents from sharing the same history and duplicating work.

Fixes #25533

Isolate subagent thread context by incorporating parentCallId into agentId.
This prevents parallel subagents from sharing the same history and duplicating work.

Fixes #25533

TAG=agy
CONV=4043d296-611e-448a-a9d9-cd78f122b436
@akh64bit akh64bit requested a review from a team as a code owner May 4, 2026 16:10
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where parallel subagents were sharing the same history and duplicating work by failing to maintain distinct thread contexts. By modifying the agent ID generation to include the parent call identifier, the system now correctly isolates subagent execution, preventing state collisions and redundant processing.

Highlights

  • Agent ID Isolation: Updated the agent ID generation logic to incorporate the parentCallId, ensuring that subagents have unique identifiers.
  • Test Suite Update: Refactored the local executor tests to verify that the agent ID correctly includes the parentCallId when running within a tool call context.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-cli gemini-cli Bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label May 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Size Change: +160 B (0%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-33N3ODP4.js 0 B -657 kB (removed) 🏆
./bundle/chunk-4GQI3BFW.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-D35OVGLA.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-EOGNTHVC.js 0 B -2.72 MB (removed) 🏆
./bundle/chunk-EQW5FCO2.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-F3UYU2HH.js 0 B -12.5 kB (removed) 🏆
./bundle/chunk-L4W2WAZQ.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-PCI4Q46Y.js 0 B -14.7 MB (removed) 🏆
./bundle/core-QN7CTODL.js 0 B -48.5 kB (removed) 🏆
./bundle/devtoolsService-ZDL2G6GA.js 0 B -28 kB (removed) 🏆
./bundle/gemini-UIDTWJSR.js 0 B -582 kB (removed) 🏆
./bundle/interactiveCli-EA72INYV.js 0 B -1.32 MB (removed) 🏆
./bundle/liteRtServerManager-5XDK7ITL.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-YUCV4SOD.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-FWIJH36I.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/chunk-H2PVHV4Y.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-IVJ236DB.js 12.5 kB +12.5 kB (new file) 🆕
./bundle/chunk-JZQCVPBZ.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-PF57M5LS.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-U2WYFBEZ.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-U3SA2B2A.js 657 kB +657 kB (new file) 🆕
./bundle/chunk-Z6LZH45U.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/core-3RZZ2BB4.js 48.5 kB +48.5 kB (new file) 🆕
./bundle/devtoolsService-GYKTGYEL.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-JOU23VLF.js 582 kB +582 kB (new file) 🆕
./bundle/interactiveCli-DH5SGDJP.js 1.32 MB +1.32 MB (new file) 🆕
./bundle/liteRtServerManager-JISZLL3K.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-PQMY2MAJ.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-DD4MWEAB.js 1.97 MB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-XMBIPNS2.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.1 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-HRURE3F3.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-K2G6GP3T.js 0 B -652 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-CXNU2MKO.js 932 B +932 B (new file) 🆕
./bundle/start-YDDCSSBS.js 652 B +652 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the LocalAgentExecutor to include the parentCallId in the generated agentId and adjusts the associated tests to verify this behavior. A security concern was raised regarding potential path traversal attacks if the parentCallId is not sanitized before being used in the agentId, especially if that ID is later used for file-based logging. Additionally, it is recommended to maintain the original entropy of the random suffix to prevent ID collisions when multiple subagents are spawned.

Comment on lines +313 to +315
this.agentId = parentCallId
? `${parentCallId}-${Math.random().toString(36).slice(2, 5)}`
: Math.random().toString(36).slice(2, 8);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

security-high high

There are two issues with the new agentId generation logic:

  1. Security (Path Traversal): parentCallId can originate from a model-provided tool call ID (see processFunctionCalls line 1093). If this ID is used in agentId, and agentId is subsequently used as a filename for session recording or logging, a malicious model could trigger a path traversal attack (e.g., by providing a callId like ../../evil). The parentCallId should be sanitized to include only safe characters (e.g., alphanumeric, hyphens, underscores).
  2. Entropy Reduction: The random suffix length is reduced from 6 to 3 characters when parentCallId is present. If a single tool call spawns multiple subagents in parallel, the collision risk with only 3 characters (36^3 = 46,656) is significantly higher than with 6 characters (36^6 approx 2.1 billion). Given the goal of this PR is to ensure isolation, maintaining the 6-character suffix is safer.
    const sanitizedParentId = parentCallId?.replace(/[^a-zA-Z0-9_-]/g, '_');
    this.agentId = sanitizedParentId
      ? sanitizedParentId + '-' + Math.random().toString(36).slice(2, 8)
      : Math.random().toString(36).slice(2, 8);

Address security feedback from gemini-code-assist:
- Sanitize `parentCallId` to prevent potential path traversal attacks if used in filenames.
- Restore random suffix to 6 characters to maintain entropy and avoid collisions.

TAG=agy
CONV=4043d296-611e-448a-a9d9-cd78f122b436
@akh64bit
Copy link
Copy Markdown
Contributor Author

akh64bit commented May 4, 2026

Hi @gemini-code-assist, thanks for the feedback!

I have updated the PR to address both points:

  1. Security (Path Traversal): I added sanitization for parentCallId to only allow alphanumeric characters, hyphens, and underscores.
  2. Entropy Reduction: I restored the random suffix to 6 characters to maintain entropy and avoid collisions.

The changes have been pushed.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Thank you for the update, @akh64bit. The added sanitization for parentCallId and the restoration of the random suffix are excellent improvements that address the security and entropy concerns effectively. The changes look solid.

@akh64bit akh64bit force-pushed the fix/subagent-isolation-25533 branch from 00c3826 to 6b42c28 Compare May 4, 2026 18:06
@akh64bit akh64bit requested a review from abhipatel12 May 4, 2026 23:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

I feel the subagents are duplicating work when running in parallel

1 participant