Skip to content

fix(relay/openai): normalize stop field from string to array - #5930

Closed
AinzRimuru wants to merge 1 commit into
QuantumNous:mainfrom
AinzRimuru:main
Closed

fix(relay/openai): normalize stop field from string to array#5930
AinzRimuru wants to merge 1 commit into
QuantumNous:mainfrom
AinzRimuru:main

Conversation

@AinzRimuru

@AinzRimuru AinzRimuru commented Jul 6, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

对OpenAI接口的请求体的Stop字段进行归一化处理。将String形式的Stop字段统一转换为Array,以解决部分平台不支持String输入的情况。
但考虑到当前操作涉及对请求体的重写,因此加入了Warn日志以方便排查可能存在的问题,目前本地测试一切正常。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

new-api-codex   | [WARN] 2026/0*/** - **:**:** | 20260**** | stop field normalized from string to array for channel *** (model: glm-5.2)

对应请求不再出现400报错。

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of stop sequences in OpenAI requests by normalizing single-value inputs into the expected format.
    • Added a warning when a stop value is provided in an unsupported form, helping diagnose request issues more easily.

Some strict OpenAI-compatible upstreams (Java/Jackson based, with stop
declared as ArrayList and ACCEPT_SINGLE_VALUE_AS_ARRAY disabled) reject
a single-string stop with HTTP 400. Convert a non-empty string stop to a
string slice before forwarding. Mainstream upstreams (OpenAI, Azure, etc.)
accept the array form equally well.
Copilot AI review requested due to automatic review settings July 6, 2026 07:42
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds normalization logic in ConvertOpenAIRequest so that when request.Stop is a non-empty string, it is converted into a single-element []string, with a warning logged, preventing downstream 400 errors on platforms that only accept array-typed stop sequences.

Changes

Stop field normalization

Layer / File(s) Summary
Normalize string Stop into array
relay/channel/openai/adaptor.go
Detects a string-typed request.Stop, logs a warning, and converts it to a single-element []string before continuing request conversion.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Possibly related PRs

  • QuantumNous/new-api#2779: Also normalizes/parses OpenAI request.Stop into stop sequence lists for downstream channel-specific conversion.

Poem

A string came hopping, plain and small,
"I'm not an array!" — 400 for all!
This bunny wrapped it, snug in a list,
Now every platform gets the gist. 🐰
Hop, hop, request — through without a fuss!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: normalizing the OpenAI stop field from string to array.
Linked Issues check ✅ Passed The change matches issue #5929 by converting string stop values to arrays, preventing upstream 400 errors.
Out of Scope Changes check ✅ Passed The diff is narrowly focused on stop-field normalization and adds no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI 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.

Pull request overview

This PR updates the OpenAI relay adaptor to normalize the stop request field from a single string into a one-element array when needed, improving compatibility with stricter OpenAI-compatible upstream implementations (e.g., Jackson-based servers that reject single-value inputs for array-typed fields).

Changes:

  • Normalize request.Stop when it is a non-empty string by converting it to []string{stop}.
  • Add a warning log when this normalization occurs to aid troubleshooting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +234 to +242
// 归一化 stop 字段:某些严格的 OpenAI 兼容上游(基于 Java/Jackson,将 stop 声明为
// ArrayList 且未启用 ACCEPT_SINGLE_VALUE_AS_ARRAY)收到单字符串会返回 400。
// 转成数组形式,OpenAI 官方/Azure 等主流上游同样接受。
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}
Comment on lines +237 to +242
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
relay/channel/openai/adaptor.go (1)

238-240: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider downgrading log level for routine normalization.

LogWarn fires on every request with a string stop value, across all channels. Once clients commonly send string-form stop, this becomes high-volume noise for expected/handled behavior rather than an actionable warning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/openai/adaptor.go` around lines 238 - 240, The normalization
message in the OpenAI adaptor is too noisy for an expected request shape, so
reduce the log level from warning to a lower severity in the code path that logs
“stop field normalized from string to array” inside the channel adaptor
handling. Update the logger call in the relevant request-processing flow so
routine string-form stop normalization is logged as debug/info rather than warn,
while keeping the same context fields like channel ID and upstream model name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@relay/channel/openai/adaptor.go`:
- Around line 237-242: The stop normalization in adaptor.go skips empty strings
because of the s != "" guard, so a bare string stop can still be sent upstream
and trigger the same Jackson 400. Update the request.Stop handling in the
adaptor’s normalization block to convert any string value, including empty
string, into a []string, and keep the existing warning/logging around the
normalization path.

---

Nitpick comments:
In `@relay/channel/openai/adaptor.go`:
- Around line 238-240: The normalization message in the OpenAI adaptor is too
noisy for an expected request shape, so reduce the log level from warning to a
lower severity in the code path that logs “stop field normalized from string to
array” inside the channel adaptor handling. Update the logger call in the
relevant request-processing flow so routine string-form stop normalization is
logged as debug/info rather than warn, while keeping the same context fields
like channel ID and upstream model name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 41209ba6-9db6-4f63-a4c7-c1b64668e66f

📥 Commits

Reviewing files that changed from the base of the PR and between 1e80ce0 and d42c5df.

📒 Files selected for processing (1)
  • relay/channel/openai/adaptor.go

Comment on lines +237 to +242
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Empty-string stop is not normalized.

The guard s != "" skips normalization when request.Stop is an empty string. Strict Jackson-based upstreams that reject a bare string stop (the exact issue this PR fixes) would still receive a string type in that case and could return the same 400 error.

🐛 Proposed fix
-	if s, ok := request.Stop.(string); ok && s != "" {
+	if s, ok := request.Stop.(string); ok {
 		logger.LogWarn(c.Request.Context(), fmt.Sprintf(
 			"stop field normalized from string to array for channel %d (model: %s)",
 			info.ChannelId, info.UpstreamModelName))
-		request.Stop = []string{s}
+		if s == "" {
+			request.Stop = nil
+		} else {
+			request.Stop = []string{s}
+		}
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if s, ok := request.Stop.(string); ok && s != "" {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
request.Stop = []string{s}
}
if s, ok := request.Stop.(string); ok {
logger.LogWarn(c.Request.Context(), fmt.Sprintf(
"stop field normalized from string to array for channel %d (model: %s)",
info.ChannelId, info.UpstreamModelName))
if s == "" {
request.Stop = nil
} else {
request.Stop = []string{s}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/openai/adaptor.go` around lines 237 - 242, The stop
normalization in adaptor.go skips empty strings because of the s != "" guard, so
a bare string stop can still be sent upstream and trigger the same Jackson 400.
Update the request.Stop handling in the adaptor’s normalization block to convert
any string value, including empty string, into a []string, and keep the existing
warning/logging around the normalization path.

@seefs001 seefs001 closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

部分平台的api未完全适配openai接口,导致请求出现400

3 participants