Skip to content

fix(serve): reject fractional max connections - #5707

Closed
tt-a1i wants to merge 1 commit into
QwenLM:mainfrom
tt-a1i:fix/serve-max-connections-integer
Closed

fix(serve): reject fractional max connections#5707
tt-a1i wants to merge 1 commit into
QwenLM:mainfrom
tt-a1i:fix/serve-max-connections-integer

Conversation

@tt-a1i

@tt-a1i tt-a1i commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Rejects fractional maxConnections values in runQwenServe before the daemon listener starts.

The existing default behavior is unchanged, and 0 / Infinity still keep the documented unlimited behavior by leaving server.maxConnections unset.

Why it's needed

maxConnections is a listener connection count cap. Fractional values like 1.5 are not meaningful for a socket count limit, but they were accepted and could be forwarded to Node's server.maxConnections.

Failing at boot keeps the cap deterministic and matches the surrounding validation style for count-based serve options.

Reviewer Test Plan

How to verify

Run npm test --workspace=packages/cli -- serve/server.test.ts -t max-connections and confirm the focused max-connections tests pass.

Review runQwenServe validation and confirm fractional maxConnections values now throw while 0, Infinity, and positive integers keep their existing behavior.

Evidence (Before & After)

Before: runQwenServe({ maxConnections: 1.5 }) passed validation and forwarded a fractional connection cap toward the Node server.

After: fractional maxConnections throws during boot. Tests cover 0, Infinity, a valid integer, NaN, a negative value, and a fractional value.

Tested on

OS Status
🍏 macOS ✅ tested
🪟 Windows ⚠️ not tested
🐧 Linux ⚠️ not tested

Environment (optional)

Local validation on macOS:

  • npm test --workspace=packages/cli -- serve/server.test.ts -t max-connections
  • npx prettier --check packages/cli/src/serve/run-qwen-serve.ts packages/cli/src/serve/server.test.ts
  • npm run lint --workspace=packages/cli --if-present
  • git diff --check
  • npm run typecheck --workspace=packages/cli --if-present ⚠️ still fails on existing unrelated src/ui/components/BaseTextInput.tsx imports from ink/dom and ink/components/CursorContext

Risk & Scope

  • Main risk or tradeoff: embedded callers that passed fractional maxConnections will now fail fast instead of relying on Node's handling of a fractional cap.
  • Not validated / out of scope: no changes to connection handling, auth, session limits, or WebSocket/SSE behavior beyond rejecting invalid listener cap values.
  • Breaking changes / migration notes: valid integer values, 0, Infinity, and the default behavior are unchanged.

Linked Issues

Fixes #5706

AI Assistance Disclosure

I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.

中文说明

What this PR does

这个 PR 会在 daemon listener 启动前,在 runQwenServe 中拒绝小数形式的 maxConnections

现有默认行为保持不变,0 / Infinity 仍然保留文档中的无限制语义,也就是不设置 server.maxConnections

Why it's needed

maxConnections 是 listener 的连接数量上限。像 1.5 这样的小数对于 socket 数量限制没有意义,但之前会被接受,并可能继续传给 Node 的 server.maxConnections

启动时直接失败能让这个 cap 的行为更确定,也和周围基于数量的 serve 选项校验风格一致。

Reviewer Test Plan

How to verify

运行 npm test --workspace=packages/cli -- serve/server.test.ts -t max-connections,确认 max-connections 的 focused tests 通过。

检查 runQwenServe 校验逻辑,确认小数 maxConnections 现在会抛错,同时 0Infinity 和正整数保留现有行为。

Evidence (Before & After)

Before:runQwenServe({ maxConnections: 1.5 }) 可以通过校验,并把小数形式的连接 cap 继续传向 Node server。

After:小数 maxConnections 会在启动阶段抛错。测试覆盖了 0Infinity、合法整数、NaN、负数和小数。

Tested on

OS Status
🍏 macOS ✅ tested
🪟 Windows ⚠️ not tested
🐧 Linux ⚠️ not tested

Environment (optional)

本地 macOS 验证:

  • npm test --workspace=packages/cli -- serve/server.test.ts -t max-connections
  • npx prettier --check packages/cli/src/serve/run-qwen-serve.ts packages/cli/src/serve/server.test.ts
  • npm run lint --workspace=packages/cli --if-present
  • git diff --check
  • npm run typecheck --workspace=packages/cli --if-present ⚠️ 仍然因为既有的无关问题失败,位置是 src/ui/components/BaseTextInput.tsxink/domink/components/CursorContext 的导入

Risk & Scope

  • Main risk or tradeoff:传入小数 maxConnections 的 embedded caller 现在会快速失败,不再依赖 Node 对小数 cap 的处理。
  • Not validated / out of scope:不修改 connection handling、auth、session limits 或 WebSocket/SSE 行为,只拒绝无效 listener cap 值。
  • Breaking changes / migration notes:合法整数、0Infinity 和默认行为都保持不变。

Linked Issues

Fixes #5706

AI Assistance Disclosure

I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.

@tt-a1i
tt-a1i marked this pull request as ready for review June 22, 2026 20:15
@wenshao

wenshao commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR @tt-a1i!

Template looks good ✓

On direction: clear bug fix — fractional connection counts are meaningless for a socket cap, and the existing validation was too permissive. Tightening this to reject fractional values matches the surrounding validation style for count-based serve options. No direction concerns.

On approach: minimal and focused. Reuses the existing isNonNegativeIntegerOrInfinity helper (already used for maxPendingPromptsPerSession), consolidates the NaN/negative/fractional tests into a clean parameterized test. No scope creep, no drive-by changes. The scope is exactly right for the stated goal.

Moving on to code review. 🔍

中文说明

感谢贡献 @tt-a1i

模板完整 ✓

方向:明确的验证逻辑修复——小数的连接数对 socket 上限没有意义,现有校验过于宽松。收紧为拒绝小数值与周围基于数量的 serve 选项校验风格一致,方向没有问题。

方案:最小化且聚焦。复用已有的 isNonNegativeIntegerOrInfinity 辅助函数(已在 maxPendingPromptsPerSession 中使用),将 NaN/负数/小数测试合并为参数化测试。没有范围蔓延,没有附带改动。范围恰好匹配目标。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code Review

Clean, focused change. The PR correctly replaces the inline (Number.isNaN(opts.maxConnections) || opts.maxConnections < 0) check with the existing isNonNegativeIntegerOrInfinity helper (already used for maxPendingPromptsPerSession at line 684). No new code introduced — just reusing an existing validator.

The parameterized test consolidation (NaN → negative → fractional) is a good DRY improvement. Comment updates are accurate.

No correctness bugs, no security issues, no regressions found.

Unit Tests

Focused max-connections tests: 6 passed (0, Infinity, valid integer 100, NaN, negative, fractional).
Broader runQwenServe suite: 61 passed, 0 failed.

 ✓ src/serve/server.test.ts (508 tests | 502 skipped) 107ms

 Test Files  1 passed (1)
      Tests  6 passed | 502 skipped (508)

Before (installed build)

Fractional --max-connections 1.5 passes validation and the daemon starts:

$ timeout 10 qwen serve --max-connections 1.5
qwen serve: daemon log → /home/runner/.qwen/debug/daemon/serve-5186-0359ff44.log
qwen serve: session reaper started (interval 60000ms, idle threshold 1800000ms)
qwen serve: Web Shell UI served from /usr/local/lib/node_modules/@qwen-code/qwen-code/web-shell
qwen serve listening on http://127.0.0.1:4170 (mode=http-bridge, workspace=/home/runner/work/qwen-code/qwen-code)
qwen serve: bound to workspace "/home/runner/work/qwen-code/qwen-code"
qwen serve: bearer auth disabled (loopback default). Set QWEN_SERVER_TOKEN to enable.
qwen serve: /acp WebSocket transport enabled on /acp
Terminated
EXIT_CODE=143

After (this PR)

Fractional --max-connections 1.5 now rejected at boot with a clear error:

$ timeout 10 npm run dev -- serve --max-connections 1.5

> @qwen-code/qwen-code@0.18.5 dev
> node scripts/dev.js serve --max-connections 1.5

DEV is set to true, but the React DevTools server is not running. Start it with:

$ npx react-devtools

qwen serve: daemon log → /home/runner/.qwen/debug/daemon/serve-5318-0359ff44.log
qwen serve: session reaper started (interval 60000ms, idle threshold 1800000ms)
qwen serve: Web Shell UI served from /home/runner/work/qwen-code/qwen-code/packages/web-shell/dist
qwen serve: Invalid maxConnections: 1.5. Must be a non-negative integer (0 / Infinity = unlimited).
EXIT_CODE=0

Before/after confirms the fix works as described. The daemon no longer silently accepts a meaningless fractional connection cap.

中文说明

代码审查

改动干净且聚焦。PR 正确地将内联的 (Number.isNaN(opts.maxConnections) || opts.maxConnections < 0) 检查替换为已有的 isNonNegativeIntegerOrInfinity 辅助函数(已在第 684 行用于 maxPendingPromptsPerSession)。没有引入新代码,只是复用了已有的验证器。

参数化测试合并(NaN → 负数 → 小数)是一个好的 DRY 改进。注释更新准确。

未发现正确性 bug、安全问题或回归。

单元测试

聚焦的 max-connections 测试:6 通过(0、Infinity、合法整数 100、NaN、负数、小数)。
更广泛的 runQwenServe 测试套件:61 通过,0 失败

对比测试

修复前(已安装版本):--max-connections 1.5 通过校验,daemon 正常启动。
修复后(此 PR):--max-connections 1.5 在启动时被拒绝,报错信息清晰:Invalid maxConnections: 1.5. Must be a non-negative integer (0 / Infinity = unlimited).

修复前/后对比确认修复符合描述。daemon 不再默默接受无意义的小数连接上限。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

This is a clean, well-scoped validation fix. The PR does exactly what it says — tightens the maxConnections check to reject fractional values by reusing an existing helper that was already doing this job for maxPendingPromptsPerSession. The before/after tmux test confirms the daemon now fails fast on 1.5 instead of silently accepting it.

The parameterized test consolidation is a nice touch — one it.each replaces the duplicated NaN/negative assertions and adds fractional coverage for free. No drive-by changes, no scope creep.

Approving. ✅

中文说明

这是一个干净、范围恰当的验证逻辑修复。PR 做了它声称的事情——通过复用已有的辅助函数来收紧 maxConnections 检查,拒绝小数值(该函数已在 maxPendingPromptsPerSession 中做同样的事)。修复前/后的 tmux 测试确认 daemon 现在对 1.5 快速失败,而不是默默接受。

参数化测试合并也很不错——一个 it.each 替代了重复的 NaN/负数断言,并免费添加了小数覆盖。没有附带改动,没有范围蔓延。

批准。✅

Qwen Code · qwen3.7-max

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, looks ready to ship. ✅

@pomelo-nwu

Copy link
Copy Markdown
Collaborator

Same pattern as #5705. maxConnections is a socket count cap. current >= 1.5 is behaviorally identical to current >= 2 for integer connection counts. Node's server.maxConnections also handles fractional values by coercion — it does not crash or behave unexpectedly.

What scenario produces maxConnections: 1.5 from an env var or config that causes a visible problem? Without a before/after reproduction, this is adding a guard for a non-existent failure mode.

Feel free to reopen with a concrete reproduction. For future PRs, please show what actually breaks.

中文说明

#5705 同一模式。maxConnections 是 socket 数量上限。对于整数连接数,current >= 1.5 等价于 current >= 2。Node 的 server.maxConnections 也通过类型转换处理小数值——不会崩溃或异常行为。

什么场景下会从环境变量或配置产生 maxConnections: 1.5 并导致可见问题?没有 before/after 复现,这就是为不存在的失败模式加防护。

欢迎带上具体复现案例重新打开。后续 PR 请展示实际会出什么问题。

@pomelo-nwu pomelo-nwu closed this Jun 22, 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.

bug(serve): maxConnections accepts fractional limits

4 participants