Skip to content

feat(provider): repair malformed SSE JSON via jsonrepair#25385

Closed
water-in-stone wants to merge 1 commit into
anomalyco:devfrom
water-in-stone:fix/parse-malformed-sse-msg
Closed

feat(provider): repair malformed SSE JSON via jsonrepair#25385
water-in-stone wants to merge 1 commit into
anomalyco:devfrom
water-in-stone:fix/parse-malformed-sse-msg

Conversation

@water-in-stone

@water-in-stone water-in-stone commented May 2, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #25247, #23442

Type of change

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

What does this PR do?

Some OpenAI-compatible providers (observed with Z.AI GLM-5.1 and Qwen) occasionally emit SSE data frames whose JSON is malformed - unescaped quotes inside content, or the next frame spliced mid-field. The AI SDK's parseJsonEventStream then throws and terminates the whole stream.

Add a byte-level TransformStream wrapper that, for each SSE event, strict-parses every data: payload first and only falls back to jsonrepair on failure. Repaired payloads are round-trip validated before being written back; unrepairable chunks pass through unchanged so the downstream parser still surfaces the original error.

Opt-in via experimental.enable_sse_json_repair (default false) to avoid any behavior change for users not hitting this bug.

by the way, jsonrepair is a popular tool used for fixing malformed JSON text from LLMs. Its key features include:

  • Automatically completing missing quotes, brackets, and commas
  • Repairing unescaped double quotes (which directly addresses the notebook issue)
  • Streaming support (jsonrepair/stream)
  • Zero dependencies, written in native TypeScript

How did you verify your code works?

Origin malformed JSON text:
image
Valid JSON text after jsonrepair
image

All the unit tests under packages/opencode/test/provider/repair-sse.test.ts have passed.
image

Checklist

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

If you do not follow this template your PR will be automatically rejected.

@water-in-stone

Copy link
Copy Markdown
Author

@kitlangton PTAL

Some OpenAI-compatible providers (observed with Z.AI GLM-5.1 and Qwen) occasionally emit SSE data frames whose JSON is malformed - unescaped quotes inside content, or the next frame spliced mid-field. The AI SDK's parseJsonEventStream then throws and terminates the whole stream.

Add a byte-level TransformStream wrapper that, for each SSE event, strict-parses every data: payload first and only falls back to jsonrepair on failure. Repaired payloads are round-trip validated before being written back; unrepairable chunks pass through unchanged so the downstream parser still surfaces the original error.

Opt-in via experimental.enable_sse_json_repair (default false) to avoid any behavior change for users not hitting this bug.
@water-in-stone water-in-stone force-pushed the fix/parse-malformed-sse-msg branch from 4bb5364 to e9853a2 Compare May 4, 2026 03:41
@water-in-stone

Copy link
Copy Markdown
Author

@rekram1-node I have created a MR with thorough testing. PTAL.

@water-in-stone

Copy link
Copy Markdown
Author

@thdxr I have created a MR with thorough testing. PTAL.

If you're short on time to review this MR, consider using AI for the code review.

By the way, I have already used Claude Code to review this MR.

@water-in-stone

Copy link
Copy Markdown
Author

@nexxeln I have created a MR with thorough testing. PTAL.

@water-in-stone

Copy link
Copy Markdown
Author

If you guys don't care about the community's voice at all, then stop wasting out time with open source.

@kitlangton @rekram1-node @thdxr @nexxeln

@github-actions

github-actions Bot commented Jun 2, 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.

JSON parsing failed: Text: - macOS / Docker

1 participant