Skip to content

fix(cli): prevent informational logs from polluting json output#26264

Merged
Adib234 merged 4 commits intomainfrom
fix-stdout-pollution-19198
Apr 30, 2026
Merged

fix(cli): prevent informational logs from polluting json output#26264
Adib234 merged 4 commits intomainfrom
fix-stdout-pollution-19198

Conversation

@cocosheng-g
Copy link
Copy Markdown
Contributor

Summary

This PR prevents informational logs (e.g. MCP discovery messages, debug logs) from polluting the stdout stream when the CLI is running in non-interactive mode with JSON output.

Details

The issue occurred because patchStdio() starts buffering output very early, but the full ConsolePatcher (which redirects console.log to stderr) is initialized later. Any logs during this window were captured as stdout and then flushed to the real stdout during the pre-session drain.

Key changes:

  • Early Redirection: Immediately after starting the capture buffer, console.log and console.info are shallow-patched to point to console.error if in headless mode.
  • Smart Draining: coreEvents.drainBacklogs now supports an optional transformer. initializeOutputListenersAndFlush uses this to force any buffered stdout items to stderr if JSON output is active.
  • Robustness: Refactored gemini.tsx to manage the config variable more reliably during the initialization and cleanup phases.

Related Issues

Fixes #19198

How to Validate

  1. Add a console.log('STRAY') at the beginning of main() in gemini.tsx.
  2. Run npm run bundle.
  3. Run node bundle/gemini.js --prompt 'hi' --output-format json > out.json.
  4. Observe that out.json is valid JSON and does not contain 'STRAY', while 'STRAY' appears in stderr.

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

@cocosheng-g cocosheng-g requested a review from a team as a code owner April 30, 2026 15:42
@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 informational logs were polluting stdout when the CLI was running in non-interactive mode with JSON output enabled. By introducing early console redirection and a flexible event transformation mechanism during the backlog flushing process, the changes ensure that diagnostic messages are correctly routed to stderr, preserving the integrity of the JSON output stream.

Highlights

  • Early Console Redirection: Implemented shallow patching of console.log and console.info to redirect to stderr during early CLI initialization in headless mode.
  • Enhanced Event Draining: Updated coreEvents.drainBacklogs to support an optional transformation function, allowing for dynamic modification of events during the flush process.
  • JSON Output Protection: Configured the output flushing mechanism to automatically redirect buffered stdout events to stderr when the CLI is configured for JSON output.
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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Size Change: +890 B (0%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-7FXC36TH.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-BWV3CGS2.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-HQ2BNR2A.js 0 B -12.6 kB (removed) 🏆
./bundle/chunk-L5S7SMIL.js 0 B -2.72 MB (removed) 🏆
./bundle/chunk-NQJDCJAK.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-P7UOP2CB.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-QW2RJHD7.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-WCDXTSYE.js 0 B -655 kB (removed) 🏆
./bundle/chunk-XRLFHCHC.js 0 B -1.97 MB (removed) 🏆
./bundle/core-F76P3CYN.js 0 B -48.2 kB (removed) 🏆
./bundle/devtoolsService-325LDILM.js 0 B -28 kB (removed) 🏆
./bundle/gemini-VVWQP7J3.js 0 B -580 kB (removed) 🏆
./bundle/interactiveCli-XP3M34EH.js 0 B -1.31 MB (removed) 🏆
./bundle/liteRtServerManager-NWL62OOM.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-N6WBYKWL.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-7SAPDJQD.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-E74KSZB7.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-HB2DPFEA.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-KWUYCBN3.js 655 kB +655 kB (new file) 🆕
./bundle/chunk-MMEGMYCS.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-OQX7GVID.js 1.97 MB +1.97 MB (new file) 🆕
./bundle/chunk-Q7VFRRQL.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/chunk-SGT422O4.js 12.6 kB +12.6 kB (new file) 🆕
./bundle/chunk-U43T64UG.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/core-SKKYYW5M.js 48.2 kB +48.2 kB (new file) 🆕
./bundle/devtoolsService-2LAD6MMC.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-5WBNUTZ2.js 580 kB +580 kB (new file) 🆕
./bundle/interactiveCli-NLKMQ6O2.js 1.31 MB +1.31 MB (new file) 🆕
./bundle/liteRtServerManager-B7CYFKKF.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-6CY4Z5IY.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-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-FAXUYKKI.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-FN3IAPBT.js 0 B -980 B (removed) 🏆
./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-PCSSMGDB.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-6KEZPFG7.js 932 B +932 B (new file) 🆕
./bundle/memoryDiscovery-QEUOLE5X.js 980 B +980 B (new file) 🆕
./bundle/start-LAI3F75Q.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 introduces console output redirection to stderr in headless mode and enhances the event backlog flushing mechanism to support event transformations. The initializeOutputListenersAndFlush function was updated to force output to stderr based on the CLI configuration, specifically for JSON output. Feedback suggests defaulting this behavior to true when the configuration is not yet initialized to prevent stdout pollution during early initialization failures.

Comment thread packages/cli/src/gemini.tsx Outdated
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

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 implements output redirection to stderr for headless mode and JSON output formats to prevent stdout pollution. Key changes include patching early console output, updating initializeOutputListenersAndFlush to handle configuration-based redirection, and enhancing the core event emitter's drainBacklogs method to support event transformation. A review comment identifies a logic issue where listener registration for console logs and user feedback is incorrectly dependent on the absence of an output listener, which could lead to lost information.

Comment thread packages/cli/src/gemini.tsx
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

@cocosheng-g cocosheng-g force-pushed the fix-stdout-pollution-19198 branch from 65648ff to 5b9b813 Compare April 30, 2026 16:00
@gemini-cli gemini-cli Bot added the area/non-interactive Issues related to GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation label Apr 30, 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 a mechanism to redirect buffered output to stderr when the CLI is in headless mode or using JSON output format. This is achieved by enhancing the core event emitter's drainBacklogs method to support event transformation and updating the CLI initialization to utilize this feature. Feedback points out a critical Temporal Dead Zone (TDZ) risk where the config variable is captured by a cleanup closure before its declaration, potentially causing a ReferenceError. Additionally, manual patching of console methods was flagged as redundant and potentially disruptive to the existing ConsolePatcher logic.

Comment thread packages/cli/src/gemini.tsx Outdated
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

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 a mechanism to redirect output to stderr when the CLI is configured for JSON output or during early initialization failures. This is achieved by enhancing the drainBacklogs method in CoreEventEmitter to support an optional transformation function. The initializeOutputListenersAndFlush function in the CLI package now utilizes this transformation to force output chunks to stderr when necessary. New unit tests have been added to verify the redirection logic and the event transformation capabilities. I have no feedback to provide.

@Adib234 Adib234 added this pull request to the merge queue Apr 30, 2026
Merged via the queue into main with commit 8c1e255 Apr 30, 2026
46 of 47 checks passed
@Adib234 Adib234 deleted the fix-stdout-pollution-19198 branch April 30, 2026 18:47
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/non-interactive Issues related to GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Event feedback breaks json output mode

2 participants