Skip to content

fix(core): filter chatcmpl-dummy SSE frames from Responses API stream - #30919

Closed
ben-wangz wants to merge 2 commits into
anomalyco:devfrom
ben-wangz:fix/sse-filter-chatcmpl-dummy
Closed

ben-wangz wants to merge 2 commits into
anomalyco:devfrom
ben-wangz:fix/sse-filter-chatcmpl-dummy

Conversation

@ben-wangz

@ben-wangz ben-wangz commented Jun 5, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #30916

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Some OpenAI-compatible gateways serving the Responses API (/v1/responses) emit a synthetic SSE frame at the start of the stream with id: "chatcmpl-dummy" and object: "chat.completion.chunk" before the real Responses API events. This frame has empty content ("content":"") and no event: prefix, so it is not a valid Responses API event.

When the AI SDK receives this frame, it tries to validate it against the Responses API event schema union, which fails with a TypeValidationError that terminates the agent turn immediately. All subsequent real events are lost.

The fix pipes the SSE response body through a TransformStream in the custom fetch wrapper inside resolveSDK(). Each chunk is split into SSE frames; if a data: line parses as JSON and has id === "chatcmpl-dummy", that frame is dropped. All other frames pass through unchanged.

The filter is scoped to Responses API calls only (URL contains /responses and content-type is text/event-stream), so it does not affect Chat Completions streams or other providers.

How did you verify your code works?

  • Built a standalone binary and tested against the proxy that reproduces the issue: opencode run "say hi" --model openai/gpt-5.5 no longer errors.
  • Confirmed the same binary works with deepseek/deepseek-v4-pro (no regression).
  • Confirmed the official release v1.15.13 exhibits the same bug and the fix resolves it.
  • Confirmed non-streaming Responses API (no chatcmpl-dummy frame) continues to work.
  • Typechecked with tsgo --noEmit in packages/opencode.

Screenshots / recordings

N/A — not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Update: the filtering is now configurable through opencode.json via provider options, for example provider.openai.options.filterSseFrame.
By default, no SSE frames are filtered. The filter only runs when filterSseFrame is explicitly configured, so existing users are unaffected.

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Responses API SSE stream starts with a synthetic chatcmpl-dummy frame causing TypeValidationError

1 participant