Skip to content

fix(core): resolve Plan Mode deadlock during plan file creation#24047

Open
DavidAPierce wants to merge 14 commits intomainfrom
plan_mode_loop_fix
Open

fix(core): resolve Plan Mode deadlock during plan file creation#24047
DavidAPierce wants to merge 14 commits intomainfrom
plan_mode_loop_fix

Conversation

@DavidAPierce
Copy link
Copy Markdown
Contributor

Summary

This PR resolves a deadlock in Plan Mode where the agent could not create its plan file if the parent directory (e.g., .gemini/plans) did not exist on the host machine. This was caused by sandbox restrictions preventing both directory creation and the binding of non-existent paths.

Details

The fix implements a proactive, path-specific permission strategy and host-side initialization:

  • EnterPlanModeTool: Now pre-creates the plans directory on the host before entering the sandbox.
  • Virtual Command Translation: Implemented translation for __read and __write in Linux (Bubblewrap) and macOS (Seatbelt) sandbox managers. This allows SandboxedFileSystemService to perform these operations using standard system tools (cat, sh) even when run_shell_command is blocked.
  • Parent Directory Binding (Linux): Updated LinuxSandboxManager to allow binding the parent directory of an explicitly allowed but non-existent path.
  • Error Handling: Enhanced SandboxedFileSystemService to correctly identify and propagate platform-specific ENOENT error strings (e.g., Windows "Could not find a part of the path"), allowing write_file to handle "new file" scenarios correctly.
  • Granular Policies: Ensured that specific file paths and write permissions are passed to the sandbox during file operations.

Related Issues

Fixes #23958

How to Validate

  1. Run the new unit tests:
    npm test -w @google/gemini-cli-core -- src/services/sandboxedFileSystemService.test.ts src/sandbox/linux/LinuxSandboxManager.test.ts src/sandbox/macos/MacOsSandboxManager.test.ts src/tools/enter-plan-mode.test.ts
  2. Manually verify by entering Plan Mode and saving a plan when the .gemini/plans directory does not exist.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

This PR resolves a deadlock in Plan Mode where the agent could not create its plan file if the parent directory (e.g., .gemini/plans) did not exist on the host machine. This was caused by sandbox restrictions preventing both directory creation and binding of non-existent paths.

Key changes:
- updated EnterPlanModeTool to pre-create the plans directory on the host.
- Implemented virtual command translation (__read/__write) for Linux and macOS sandboxes.
- Enhanced SandboxedFileSystemService to recognize platform-specific ENOENT error strings (Linux/Windows).
- Updated LinuxSandboxManager to allow binding the parent directory of explicitly allowed but non-existent paths.
- Ensured operation-specific policies are passed to the sandbox during file operations.

Fixes #23958
@DavidAPierce DavidAPierce requested review from a team as code owners March 27, 2026 19:31
@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 a deadlock in Plan Mode where the agent was unable to create plan files due to sandbox restrictions when the target directory did not exist. By implementing proactive host-side directory creation and translating virtual file system commands into native shell operations, the changes ensure that the sandbox environment is correctly prepared for file operations. Additionally, the update improves error propagation to handle missing file scenarios gracefully across different platforms.

Highlights

  • Proactive Directory Initialization: Updated EnterPlanModeTool to pre-create the plans directory on the host, ensuring it exists before sandbox binding occurs.
  • Virtual Command Translation: Implemented translation for __read and __write commands in both Linux and macOS sandbox managers to use native system tools like cat and sh, bypassing sandbox restrictions.
  • Sandbox Binding Improvements: Enhanced LinuxSandboxManager to allow binding the parent directory of non-existent paths, facilitating file creation within sandboxed environments.
  • Error Handling: Improved SandboxedFileSystemService to correctly identify and propagate platform-specific ENOENT errors, enabling better handling of new file scenarios.
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 area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Mar 27, 2026
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 introduces virtual commands (__read and __write) to the Linux and macOS sandbox managers to standardize file system access and updates the SandboxedFileSystemService to utilize these commands with appropriate policies. It also ensures that the plans directory exists on the host before entering plan mode and improves error handling by mapping file-not-found errors to the ENOENT code. The review feedback identifies critical security vulnerabilities regarding path traversal in the SandboxedFileSystemService due to a lack of path sanitization. Additionally, the reviewer pointed out a logic error in the Linux sandbox manager where parent directories for non-existent files must be mounted as read-write to allow for file creation, necessitating changes to both the implementation and the associated tests.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • 🚀 Maintainer Reminder: Please ensure that these changes do not regress results on benchmark evals before merging.

This is an automated guidance message triggered by steering logic signatures.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

Size Change: +3.05 kB (+0.01%)

Total Size: 26.5 MB

Filename Size Change
./bundle/chunk-65HI73T2.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-H2FMDFMD.js 0 B -3.77 MB (removed) 🏆
./bundle/core-YABWHV5Z.js 0 B -44.4 kB (removed) 🏆
./bundle/devtoolsService-UHIZSPHG.js 0 B -28.4 kB (removed) 🏆
./bundle/interactiveCli-F6VJL6K5.js 0 B -1.63 MB (removed) 🏆
./bundle/oauth2-provider-DXELQ4HN.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-3DI3VMRW.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-IHRFS63M.js 3.77 MB +3.77 MB (new file) 🆕
./bundle/core-ZXQ4JMZS.js 44.4 kB +44.4 kB (new file) 🆕
./bundle/devtoolsService-SEOFJE4J.js 28.4 kB +28.4 kB (new file) 🆕
./bundle/interactiveCli-6KICTQL4.js 1.63 MB +1.63 MB (new file) 🆕
./bundle/oauth2-provider-QV2NHJ7D.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
./bundle/chunk-34MYV7JD.js 2.45 kB
./bundle/chunk-5AUYMPVF.js 858 B
./bundle/chunk-664ZODQF.js 124 kB
./bundle/chunk-DAHVX5MI.js 206 kB
./bundle/chunk-IUUIT4SU.js 56.5 kB
./bundle/chunk-RJTRUG2J.js 39.8 kB
./bundle/chunk-U4FACSVX.js 1.13 kB
./bundle/chunk-WESYPIHN.js 1.96 MB
./bundle/devtools-36NN55EP.js 696 kB
./bundle/dist-T73EYRDX.js 356 B
./bundle/events-CLX3JQHP.js 418 B
./bundle/gemini.js 532 kB
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB
./bundle/memoryDiscovery-3DTYRD65.js 922 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB
./bundle/src-QVCVGIUX.js 47 kB
./bundle/tree-sitter-7U6MW5PS.js 274 kB
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB

compressed-size-action

- Ensure paths passed to SandboxedFileSystemService are sanitized and validated to be inside the workspace.

- Bind missing parent directories as writable when the command is '__write' in LinuxSandboxManager.

- Add a behavioral evaluation for entering plan mode and creating a plan file from scratch.
…across platforms

- Added support for virtual commands (__read, __write) in WindowsSandboxManager using cmd.exe and PowerShell.

- Integrated includeDirectories into Windows, Linux, and macOS sandbox managers to grant read access.

- Improved directory pre-creation logic in Windows and Linux managers for sandboxed writes.

- Fixed initialization order in Config constructor to prevent TypeScript errors.
# Conflicts:
#	packages/core/src/sandbox/windows/WindowsSandboxManager.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plan Mode deadlock: cannot create plan file when parent directory doesn't exist due to sandbox restrictions

1 participant