Skip to content

fix: enhance isBinary function to reduce false positives in PTY mode - #25191

Closed
khairul111010 wants to merge 1 commit into
google-gemini:mainfrom
khairul111010:fix/isbinary-pty-false-positive-25164
Closed

fix: enhance isBinary function to reduce false positives in PTY mode#25191
khairul111010 wants to merge 1 commit into
google-gemini:mainfrom
khairul111010:fix/isbinary-pty-false-positive-25164

Conversation

@khairul111010

Copy link
Copy Markdown

Summary

Fix isBinary() false-positive on Windows PTY streams that causes run_shell_command to always return empty output. When node-pty is used on Windows, ANSI/VT control sequences containing null bytes trigger the binary detection heuristic, halting the output stream before any content reaches the model. This makes the entire agentic workflow non-functional on Windows with interactive shell enabled.

Details

The root cause is in isBinary() (packages/core/src/utils/textUtils.ts), which treats any single null byte in the first 512 bytes as binary data. While correct for files, this is a false positive for PTY streams — node-pty on Windows emits VT/ANSI escape sequences that can contain null bytes at the start of every output stream.

Changes made:

  1. packages/core/src/utils/textUtils.ts

    • Added a private stripAnsiFromBuffer() helper that strips CSI, OSC, and simple two-byte ANSI escape sequences from raw byte buffers.
    • Extended isBinary() with an optional isPtyOutput parameter (default false). When true, ANSI sequences are stripped before checking, and a 10% null-byte ratio threshold is used instead of failing on a single null byte.
    • Default behavior (isPtyOutput=false) is completely unchanged — backward compatible.
  2. packages/core/src/services/shellExecutionService.ts

    • In executeWithPty() (line 1131): changed isBinary(sniffBuffer)isBinary(sniffBuffer, 512, true) to opt into PTY-aware detection.
    • childProcessFallback() is unchanged — it uses pipes, not PTY, so no ANSI false positives occur there.
  3. packages/core/src/utils/textUtils.test.ts

    • Added isBinary to the import.
    • Added comprehensive test suite covering both non-PTY (strict) and PTY-aware modes, including realistic Windows PTY scenarios with OSC title sequences, stray nulls, and ANSI resets.

Related Issues

Fixes #25164

How to Validate

  1. On Windows with enableInteractiveShell: true:

    gemini
    > run a simple command like "echo hello"

    Expected: Command output (hello) is returned correctly instead of empty output.

  2. Verify binary detection still works (any platform):

    gemini
    > cat a binary file like an image (e.g., "cat image.png")

    Expected: [Binary output detected. Halting stream...] message appears as before.

  3. Run the test suite:

    cd packages/core
    npx vitest run src/utils/textUtils.test.ts

    Expected: All existing tests pass, plus the new isBinary tests pass.

  4. Edge cases to verify:

    • PTY output that is entirely ANSI escape sequences → not binary
    • PTY output with a single stray null byte among text → not binary
    • Actual binary data through PTY (>10% nulls after ANSI strip) → detected as binary
    • Non-PTY child_process path → unchanged strict behavior

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any) — None; fully backward compatible
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows ← Primary platform for this fix
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@khairul111010
khairul111010 requested a review from a team as a code owner April 11, 2026 18:52
@google-cla

google-cla Bot commented Apr 11, 2026

Copy link
Copy Markdown

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.

@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 critical issue where interactive shell commands on Windows return empty output due to false-positive binary detection. By introducing PTY-aware heuristics that account for ANSI escape sequences and adjusting the null-byte detection threshold, the changes ensure that legitimate text output from PTY streams is correctly identified while maintaining strict binary detection for standard file operations.

Highlights

  • Enhanced Binary Detection: Updated the isBinary function to support an optional PTY-aware mode, which uses a 10% null-byte ratio threshold instead of failing on a single null byte.
  • ANSI Sequence Stripping: Added a helper function to strip ANSI/VT escape sequences from buffers, preventing false positives caused by control characters in PTY streams.
  • PTY Integration: Updated shellExecutionService to utilize the new PTY-aware binary detection, ensuring interactive shell output on Windows is correctly processed.
  • Comprehensive Testing: Added a new test suite covering various PTY scenarios, including ANSI sequences, stray null bytes, and realistic Windows terminal 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.

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

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.

Code Review

This pull request improves binary data detection for PTY output by implementing ANSI escape sequence stripping and a ratio-based null-byte threshold in the isBinary utility. These changes address false positives encountered in Windows PTY streams. The review feedback identifies a missing import in the new test suite and recommends requiring more than one null byte for PTY-mode detection to avoid false positives on short strings.

describe('isBinary', () => {
describe('non-PTY mode (default)', () => {
it('should return false for null/undefined input', () => {
expect(isBinary(null)).toBe(false);

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.

high

The isBinary function is used throughout this new test suite, but it has not been added to the imports at the top of the file (line 8). This will cause the tests to fail with a ReferenceError when executed.

References
  1. Before flagging a dependency as missing, verify that it does not already exist in the codebase.

nullCount++;
}
}
return nullCount / sample.length > NULL_BYTE_THRESHOLD;

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.

high

The 10% null-byte threshold (0.1) is quite strict for short PTY outputs. For example, a single stray null byte in a 6-byte string (as seen in the test case on line 233 of textUtils.test.ts) results in a ratio of ~16.7%, which exceeds the threshold and will cause isBinary to return true. This likely causes that specific test case to fail.

Consider requiring more than one null byte to trigger the ratio-based detection in PTY mode to better handle short, noisy streams.

Suggested change
return nullCount / sample.length > NULL_BYTE_THRESHOLD;
return nullCount > 1 && nullCount / sample.length > NULL_BYTE_THRESHOLD;

@gemini-cli gemini-cli Bot added the area/core Issues related to User Interface, OS Support, Core Functionality label Apr 11, 2026
@gemini-cli gemini-cli Bot added the help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! label Apr 13, 2026
@gemini-cli gemini-cli Bot added the priority/p1 Important and should be addressed in the near term. label May 8, 2026
@scidomino

Copy link
Copy Markdown
Collaborator

already merged #26565 for the same thing

@scidomino scidomino closed this May 18, 2026
@sripasg sripasg added the size/m A medium sized PR label Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p1 Important and should be addressed in the near term. size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] run_shell_command always returns empty output — isBinary() false-positive on node-pty PTY stream

3 participants