Prhub

#21900 Return HTTP 400 for streaming validation errors

原始 PR 作者 hnyls2002 合并时间 2026-04-02 12:58 文件变更 3 提交数 3 评论 8 代码增减 +59 / -4

执行摘要

修复流式请求验证错误返回 HTTP 200 而非 400 的问题,确保与 vLLM 行为一致。

根据Issue #19996描述,对于输入令牌超过上下文长度的请求,SGLang的OpenAI兼容API在流式和非流式模式下行为不一致:非流式请求正确返回HTTP 400,而流式请求返回HTTP 200并附带错误负载(error.code=400)。这与vLLM的行为不符,vLLM在两种情况下均返回HTTP 400。PR的目标是统一错误处理,使流式请求在验证失败时也返回HTTP 400。

该PR值得精读,特别是对于处理OpenAI兼容API和流式响应的开发者。关注点包括:预启动生成器的设计决策、stream_started标志的使用以避免错误吞没,以及如何平衡错误处理与流式响应性能。

讨论亮点

由于review评论为空,无法提供具体讨论内容。但根据提交历史,作者在三次提交中逐步完善了解决方案:首次提交引入预启动生成器;第二次添加测试;第三次修复了生成器内部try/except吞没验证错误的问题,通过添加stream_started标志确保错误正确传播。

实现拆解

实现方案涉及三个关键文件:1. 在serving_chat.pyserving_completions.py_handle_streaming_request方法中,通过预启动异步生成器(调用__anext__())来触发验证逻辑。如果验证失败(如抛出ValueError),则直接返回HTTP 400错误响应。2. 在_generate_chat_stream_generate_completion_stream方法中添加stream_started标志,确保验证错误在流开始前能传播到调用方。3. 在测试文件test_request_length_validation.py中添加流式请求的验证测试。

文件 模块 状态 重要度
python/sglang/srt/entrypoints/openai/serving_chat.py openai_server modified 8.0
python/sglang/srt/entrypoints/openai/serving_completions.py openai_server modified 8.0
test/registered/openai_server/validation/test_request_length_validation.py test modified 7.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

_handle_streaming_request _generate_chat_stream _generate_completion_stream

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 回归风险:修改了流式请求的错误处理路径,可能影响正常流式请求的响应生成。2. 性能风险:预启动生成器增加了额外的异步调用,可能轻微增加延迟,但仅在验证失败时才有额外开销。3. 兼容性风险:改变了API行为,从返回HTTP 200改为HTTP 400,可能影响依赖旧行为的客户端。4. 测试覆盖:新增测试覆盖了流式请求的验证场景,但需确保其他错误场景(如令牌数超限)也被覆盖。
  1. 用户影响:客户端在流式请求验证失败时将收到HTTP 400而非200,需更新错误处理逻辑以匹配新行为。2. 系统影响:统一了错误处理逻辑,提升了API与vLLM的兼容性,减少了不一致性。3. 团队影响:修复了长期存在的bug,减少了维护负担,测试覆盖增强了代码可靠性。
API 行为变更 核心路径修改 错误处理逻辑调整

关联 Issue

#19996 [Bug] /v1/chat/completions with stream=true returns HTTP 200 for context overflow error (vLLM returns 400)

完整报告

执行摘要

该PR修复了SGLang OpenAI兼容API中流式请求验证错误返回状态码不一致的bug。当输入令牌超过上下文长度时,流式请求(stream=true)现在会正确返回HTTP 400,而非之前的HTTP 200附带SSE错误负载。这一变更统一了与vLLM的行为,提升了API的兼容性和一致性。实现通过预启动流式生成器来捕获验证错误,确保在HTTP响应发送前返回正确状态码。

功能与动机

根据Issue #19996,用户报告在输入令牌数超过模型上下文长度时,SGLang的/v1/chat/completions端点行为不一致:非流式请求正确返回HTTP 400,而流式请求返回HTTP 200并附带错误负载(error.code=400)。这与vLLM的行为不符,vLLM在两种情况下均返回HTTP 400。PR的目标是修复此不一致性,使流式请求在验证失败时也返回HTTP 400,从而提升API的标准化和客户端兼容性。

实现拆解

实现涉及三个关键文件,按模块拆解如下:

  1. OpenAI服务器模块

    • serving_chat.pyserving_completions.py中的_handle_streaming_request方法被修改,返回类型从StreamingResponse扩展为Union[StreamingResponse, ErrorResponse]
    • 新增预启动逻辑:通过await generator.__anext__()触发验证,如果捕获ValueError则直接返回create_error_response(HTTP 400)。
    • 代码示例:
      try:
          first_chunk = await generator.__anext__()
      except ValueError as e:
          return self.create_error_response(str(e))
      
  2. 流生成逻辑

    • _generate_chat_stream_generate_completion_stream方法中添加stream_started标志,初始为False
    • 在首次yield后设置stream_started = True,确保验证错误在流开始前能通过raise传播到调用方。
    • 修改try/except块,仅在stream_startedFalse时重新抛出验证错误。
  3. 测试模块

    • test_request_length_validation.py新增test_input_length_longer_than_context_length_streaming测试,验证流式请求在上下文超限时抛出openai.BadRequestError(对应HTTP 400)。

评论区精华

由于review评论为空,无具体讨论内容可提炼。但提交历史显示作者通过三次提交逐步完善解决方案:

  • 首次提交引入预启动生成器机制。
  • 第二次提交添加测试覆盖。
  • 第三次提交修复生成器内部错误吞没问题,通过stream_started标志确保验证错误正确传播。

风险与影响

  • 技术风险:预启动生成器可能轻微增加流式请求的延迟,但仅在验证失败时有额外开销;修改核心错误处理路径需谨慎测试以避免回归。
  • 兼容性影响:API行为从返回HTTP 200改为HTTP 400,可能破坏依赖旧行为的客户端,需在更新日志中明确说明。
  • 测试覆盖:新增测试覆盖了上下文长度超限场景,但建议扩展测试以覆盖其他验证错误(如令牌数超限)。
  • 性能影响:对正常流式请求影响极小,因为预启动仅涉及一次异步调用。

关联脉络

  • 与Issue #19996直接关联,解决了该bug报告中描述的不一致性问题。
  • 在近期历史PR中,PR #21463(迁移API端点)同样关注API表面的一致性,但本PR更专注于错误处理逻辑。
  • 本PR是OpenAI兼容API维护的一部分,反映了团队对标准化和兼容性的持续投入。

参与讨论