Skip to content

fix(a2a-server): delimit SSE events with a blank line in /executeCommand#27549

Open
Pluviobyte wants to merge 1 commit into
google-gemini:mainfrom
Pluviobyte:fix/a2a-server-sse-event-framing
Open

fix(a2a-server): delimit SSE events with a blank line in /executeCommand#27549
Pluviobyte wants to merge 1 commit into
google-gemini:mainfrom
Pluviobyte:fix/a2a-server-sse-event-framing

Conversation

@Pluviobyte
Copy link
Copy Markdown

@Pluviobyte Pluviobyte commented May 29, 2026

Summary

The streaming /executeCommand endpoint in the A2A server emits Server-Sent Events that are not separated by a blank line, so a spec-compliant SSE/EventSource client cannot parse the individual events. This is a one-line framing fix plus a test that actually exercises the path.

Details

In packages/a2a-server/src/http/app.ts each event was written as:

res.write(`data: ${JSON.stringify(jsonRpcResponse)}\n`);

Per the SSE spec, an event is only dispatched when a blank line (\n\n) is encountered. With a single \n, consecutive data: lines are concatenated into one record and the final event is never terminated, so a real EventSource consumer ends up with one malformed event instead of N. The rest of the codebase already uses \n\n for SSE (see packages/core/src/code_assist/server.test.ts). The fix appends the missing newline.

While fixing this I found the existing streaming test never actually asserted anything: it used the Mocha-style done callback, which Vitest 3 does not honor, so the test body returned before the res.on('end') assertions ran and it passed regardless of output. I converted it to async/await (matching the other SSE tests in the file) so it genuinely validates the stream — it fails before this fix (expected 1 to be 2) and passes after.

Related Issues

Fixes #27587

How to Validate

cd packages/a2a-server
npm run typecheck
npx vitest run src/http/app.test.ts   # 20 passed

To see the bug without the production fix, revert only the app.ts change and re-run the streaming test — it fails with expected 1 to be 2, confirming the new test guards the regression.

Pre-Merge Checklist

  • Updated relevant documentation and README (not needed — internal behavior fix)
  • Added/updated tests (converted the ineffective streaming test into a real regression test)
  • Noted breaking changes (none — output becomes spec-compliant SSE)
  • Validated on required platforms/methods:
    • Linux
      • npm run (vitest + tsc --noEmit for @google/gemini-cli-a2a-server)

Note: this is a platform-independent string-framing change covered by automated unit tests, so it was validated via the package test suite on Linux rather than the full per-OS runtime matrix.

@Pluviobyte Pluviobyte requested a review from a team as a code owner May 29, 2026 06:48
@google-cla
Copy link
Copy Markdown

google-cla Bot commented May 29, 2026

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 protocol non-compliance issue in the A2A server's streaming /executeCommand endpoint. By correctly delimiting SSE events with a blank line, it ensures that standard EventSource clients can properly parse individual events. Additionally, the existing streaming test was refactored to be truly asynchronous, providing a reliable regression test for this fix.

Highlights

  • SSE Protocol Compliance: Updated the /executeCommand endpoint to append a double newline (\n\n) to SSE events, ensuring compliance with the Server-Sent Events specification for proper event dispatching.
  • Test Suite Refactoring: Converted the streaming test from a callback-based implementation to an async/await pattern to ensure assertions are correctly executed and validated.
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 the 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 counterproductive. 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.

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 SSE streaming response in packages/a2a-server/src/http/app.ts to terminate events with a double newline (\n\n) to comply with the Server-Sent Events specification. It also refactors the /executeCommand streaming E2E test in app.test.ts to use async/await and parse the full response text directly, simplifying the test logic. There are no review comments, so I have no feedback to provide.

The streaming `/executeCommand` handler wrote each Server-Sent Event with a
single trailing newline (`data: <json>\n`). The SSE specification requires
events to be separated by a blank line (`\n\n`); without it a spec-compliant
EventSource client coalesces every event into one record and never dispatches a
well-formed event, so streaming command output is unusable for real clients.

The existing streaming test did not catch this because it used the Mocha-style
`done` callback, which Vitest 3 does not honour: the test body returned before
its assertions ran, so the test always passed regardless of the payload. Convert
that test to async/await so it actually verifies the emitted events. It fails
before this fix (1 event parsed instead of 2) and passes after.
@Pluviobyte Pluviobyte force-pushed the fix/a2a-server-sse-event-framing branch from e1ade13 to e98c346 Compare May 29, 2026 07:00
@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label May 29, 2026
@gemini-cli gemini-cli Bot added priority/p2 Important but can be addressed in a future release. area/non-interactive Issues related to GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation and removed status/need-issue Pull requests that need to have an associated issue. labels May 30, 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 priority/p2 Important but can be addressed in a future release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: /executeCommand SSE stream omits blank-line event delimiters

1 participant