gemini-cli - ✅(Solved) Fix Fix shell command wrapping breaking heredocs [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#25536Fetched 2026-04-17 08:55:31
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Assignees
Timeline (top)
labeled ×3unlabeled ×2assigned ×1commented ×1

Root Cause

Summary: run_shell_command wraps the user's command in a bash group command { <command>; }; __code=0; ... (in useExecutionLifecycle.ts). This breaks all heredoc-terminated commands because the ; is appended directly to the heredoc delimiter, making bash unable to recognize it.

Fix Action

Fixed

PR fix notes

PR #25537: fix(cli): use newline in shell command wrapping to avoid breaking heredocs

Description (problem / solution / changelog)

Summary

This PR fixes a bug in shell command wrapping where heredoc commands ending with a delimiter (e.g., EOF) would fail due to an appended semicolon.

Details

The CLI was wrapping user commands like this: { <command>; };. If <command> ended in a heredoc delimiter, it would become EOF; };, which bash does not recognize as a valid end to the heredoc.

The fix replaces the semicolon with a newline: { <command>\n}; . This ensures that any final line of the user command is preserved on its own line before the closing brace, which is the correct way to end a heredoc and also serves as a valid command separator for bash.

Related Issues

Closes #25536 Related to b/492221980

How to Validate

  1. Run a shell command in the CLI that ends with a heredoc:
    cat << 'EOF' > output.txt
    hello world
    EOF
  2. Verify that the command succeeds and creates output.txt with the correct content.
  3. Run unit tests to confirm existing wrapping logic and new heredoc test cases:
    npm test packages/cli/src/ui/hooks/useExecutionLifecycle.test.tsx
    npm test packages/core/src/tools/shell.test.ts

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on MacOS (npm run)

Changed files

  • packages/cli/src/ui/hooks/useExecutionLifecycle.test.tsx (modified, +25/-11)
  • packages/cli/src/ui/hooks/useExecutionLifecycle.ts (modified, +29/-17)
  • packages/core/src/tools/shell.test.ts (modified, +59/-33)
  • packages/core/src/tools/shell.ts (modified, +24/-12)
RAW_BUFFERClick to expand / collapse

Summary: run_shell_command wraps the user's command in a bash group command { <command>; }; __code=0; ... (in useExecutionLifecycle.ts). This breaks all heredoc-terminated commands because the ; is appended directly to the heredoc delimiter, making bash unable to recognize it.

Steps to Reproduce: Run a shell command ending in a heredoc: cat << 'EOF' > output.txt hello world EOF

The CLI transforms this into: { cat << 'EOF' > output.txt hello world EOF; }; __code=0; pwd > "/tmp/xxx"; exit ;

Proposed Fix: In packages/cli/src/ui/hooks/useExecutionLifecycle.ts, replace the semicolon with a newline before closing the brace: commandToExecute = { ${command}\n}; __code=$?; pwd > "${pwdFilePath}"; exit $__code;

Impact: Heredocs fail if the delimiter is on the final line, causing model retries and token waste.

I have verified the fix with reproduction scripts and added unit tests in packages/cli and packages/core.

extent analysis

TL;DR

Replace the semicolon with a newline before closing the brace in the useExecutionLifecycle.ts file to fix the issue with heredoc-terminated commands.

Guidance

  • Verify that the problem occurs when running shell commands with heredocs, as described in the reproduction steps.
  • Check the useExecutionLifecycle.ts file to confirm that the semicolon is being appended directly to the heredoc delimiter.
  • Apply the proposed fix by replacing the semicolon with a newline before closing the brace, as shown in the commandToExecute assignment.
  • Test the fix with the provided reproduction scripts and unit tests to ensure that heredocs are properly recognized.

Example

// In packages/cli/src/ui/hooks/useExecutionLifecycle.ts
commandToExecute = `{ ${command}\n}; __code=$?; pwd > "${pwdFilePath}"; exit $__code`;

Notes

This fix assumes that the issue is solely caused by the semicolon being appended to the heredoc delimiter. If other issues arise, further investigation may be necessary.

Recommendation

Apply the workaround by replacing the semicolon with a newline before closing the brace, as this fix has been verified with reproduction scripts and unit tests.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING