Skip to content

[Bugfix][Frontend] Reject an empty conversation in every renderer - #62218

Open
albertoperdomo2 wants to merge 6 commits into
vllm-project:mainfrom
albertoperdomo2:fix/renderer-empty-conversation
Open

albertoperdomo2 wants to merge 6 commits into
vllm-project:mainfrom
albertoperdomo2:fix/renderer-empty-conversation

Conversation

@albertoperdomo2

Copy link
Copy Markdown
Contributor

Overview

Renderers with their own chat encoding (DeepSeek V3.2/V4/V4.1) render an empty conversation to a bare BOS prompt, so /v1/responses with input: [] returns 200 with text generated from nothing. This returns the same 400 that HF-tokenizer models already return.

Claims

  • An empty conversation now returns 400 BadRequestError ("Cannot apply chat template to an empty conversation. Provide at least one message.") for every renderer.
  • Non-empty conversations are unchanged, including Responses requests with input: [] plus instructions or previous_response_id.

Validation

New tests/renderers/test_empty_conversation.py: the 3 rejection cases fail on main and pass with this change; the 2 controls pass on both.

Details

transformers refuses an empty conversation in apply_chat_template, but the DeepSeek tokenizers override that method and skip the check. The check now runs at the start of BaseRenderer.render_chat and render_chat_async, after each endpoint has built its messages. The Rust frontend already rejects an empty conversation (ChatRequest::validate); this brings the Python frontend in line.

Claude Code used to create the new tests.


Pull Request Checklist
  • I used vLLM's /pr-checklist skill. (Mandatory for agents, optional for humans).

  • AI assistance was used during the creation of this PR.

  • Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.

  • Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.

  • Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.

  • Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.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.

@mergify mergify Bot added the bug Something isn't working label Oct 17, 2026
Comment thread vllm/renderers/base.py
# the HF tokenizer refuses an empty conversation in apply_chat_template,
# but renderers with their own chat encoding render it to a bare BOS
# prompt. Refuse it here so every renderer answers the same way.
if any(not conversation for conversation in conversations):

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.

I don't think this is the right fix. As conversations grows larger, we should avoid introducing an additional loop.

@albertoperdomo2 albertoperdomo2 Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks for looking @chaunceyjiang! conversations here is the batch of conversations, not the messages in one, so the check is one O(1) emptiness test per conversation and it short-circuits

online serving always renders a single conversation (online_renderer.py:805), so there it's one check; only offline LLM.chat passes a batch

measured: 0.14µs for one conversation of any length, 16µs for 1000 conversations, which can be considered negligible next to rendering and tokenizing each of them IMHO

This branch has not been deployed

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants