Skip to content

[Bugfix] Handle HarmonyError in process_chunk to fix gpt-oss streaming 500s - #52055

Open
rajathpi wants to merge 3 commits into
vllm-project:mainfrom
rajathpi:fix/harmony-streaming-error
Open

[Bugfix] Handle HarmonyError in process_chunk to fix gpt-oss streaming 500s#52055
rajathpi wants to merge 3 commits into
vllm-project:mainfrom
rajathpi:fix/harmony-streaming-error

Conversation

@rajathpi

Copy link
Copy Markdown
Contributor

FIX #51977

Purpose

gpt-oss requests fail with HTTP 500 (openai_harmony.HarmonyError: unexpected tokens remaining in message header) when the model samples a malformed Harmony
message header. HarmonyParser.flush() already catches HarmonyError and
recovers by returning the raw decoded text, but process_chunk() calls
self._harmony_parser.process(token_id) with no handling, so a mid-stream parse
failure escapes to the API server and kills the request.

This gives process_chunk() the same recovery contract as flush(): on
HarmonyError, decode the buffered message tokens plus the unconsumed tail of
the chunk as raw final-channel text, emit it as a delta segment plus a completed
message, reset parser state, and stop processing the chunk. The dual-segment
shape matches what flush() already emits, so streaming, non-streaming
parse(), and the Responses message loop all surface the text. parse() and
HarmonyContext.append_output read only completed_message, so a delta-only
segment would have turned the 500 into an empty 200 instead.

Nothing the model generated is dropped, and the request completes.

Note on the trigger: the issue points at a hyphen in the tool name, but
openai_harmony 0.0.8 accepts hyphenated recipients. Reproducing directly against
the library shows the real trigger is leftover tokens in the header. A duplicated
to= clause reproduces the reporter's exact error string, which also explains why
the failure was intermittent rather than reliable.

Scope: vLLM cannot stop a model sampling a malformed header, so it has to tolerate
HarmonyError from the library. flush() established that defensive contract
already; this completes it for the mid-stream path. A leniency fix upstream in
openai_harmony would be complementary, not a substitute.

Not duplicating existing work: #51977 is unclaimed, and no open PR references it or
touches vllm/parser/harmony.py.

Test Plan

New regression test
tests/parser/test_harmony.py::test_process_chunk_recovers_from_malformed_header
drives a duplicated to= header through process_chunk, asserts the generated
text comes back as a final-channel delta segment plus a completed message instead
of an exception, then asserts a normal message parses afterwards to prove the
state reset. It fails without the source change.

pytest tests/parser/test_harmony.py tests/reasoning/test_gptoss_reasoning_parser.py

Test Result

66 passed

With vllm/parser/harmony.py reverted, the new test fails:

FAILED tests/parser/test_harmony.py::test_process_chunk_recovers_from_malformed_header

ruff check and ruff format --check clean on both files; mypy (CI
configuration) reports no issues on either file.

No model evaluation run: only the error-recovery path changes, and behaviour on
well-formed output is untouched, covered by the 65 pre-existing tests in this file.


This change was developed with AI assistance; I reviewed and tested every line.

…g 500s

process_chunk() called the Harmony streamable parser with no exception
handling, so a malformed message header (for example a duplicated `to=`
clause) raised HarmonyError all the way out to the API server and failed
the request with a 500.

flush() already catches HarmonyError and recovers by returning the raw
decoded text. Give process_chunk() the same contract: decode the buffered
tokens plus the unconsumed tail of the chunk as raw final-channel text,
emit it as a delta segment plus a completed message so streaming,
non-streaming parse(), and the Responses message loop all surface it,
reset parser state, and stop processing the chunk.

Fixes vllm-project#51977.

Assisted-by: AI coding assistant
Signed-off-by: rajathpi <rajathpai2000@gmail.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use /ci run, /ci retry, or /ci cancel. New commits do not start CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban.

🚀

@rajathpi

Copy link
Copy Markdown
Contributor Author

@claude review

@fstarosciak

Copy link
Copy Markdown

for me this looks good

@JakobKe

JakobKe commented Aug 13, 2026

Copy link
Copy Markdown

Looks good to me.

@rajathpi

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

@rajathpi, A reviewer with write access must run /ci run, approve the PR, or add the ready label first.

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

Labels

bug Something isn't working gpt-oss Related to GPT-OSS models tool-calling

Projects

Status: No status
Status: To Triage

Development

Successfully merging this pull request may close these issues.

[Bug]: openai_harmony.HarmonyError: unexpected tokens remaining in message header on v0.26.0 (gpt-oss-120b)

3 participants