Repository navigation
fix(server): request illegal 不再永久禁用账号,改为软冷却 - #198
Closed
luohaonan365 wants to merge 1 commit into
Closed
luohaonan365 wants to merge 1 commit into
luohaonan365 wants to merge 1 commit into
Conversation
上游对「渠道校验失败」的响应是 HTTP 400 code 11-128 "request illegal",body 自带 displayMsg「请求被拦截,请重新发送」与 displayTips「渠道校验失败,可能不是从官方 客户端发出的,请用官方客户端重新发送」——上游明示这是可重试的请求级拦截, 不是账号级封禁。 但 applyErrorPolicy 在 ErrAccountFault 分支按 msg 字面量匹配 "request illegal", 直接调用 Pool.Disable(),把账号永久踢出池子并要求人工解冻: h.cfg.Pool.Disable(uid, "account banned by upstream (11140 request illegal), re-login required") 实测该账号凭证/余额/JWT 全部正常,同一套出站头部换健康账号即可 200,换任何模型、 任何 header 变体都稳定复现——账号本身没有任何问题,禁用纯属误判。 改为软冷却:账号暂时出池、自动轮换,上游解除标记后自愈,绝不永久禁用。 触发该 400 的根因(缺 X-Conversation-ID)已由 linguo2625469#190 在 internal/upstream/headers.go 层修复;本 PR 是互补的防御面:即使将来上游换个措辞、或出现别的触发路径,误判的 代价也从「账号永久禁用、必须人工解冻」降为「短暂轮换、自动恢复」。 Refs linguo2625469#190 Refs linguo2625469#197
Closed
Author
|
补充一个实现细节,供权衡(本 PR 不涉及这部分,只在 #190 在 } else if len(id) != 32 || !validTraceID(id) || id == previousID {
t.Fatalf("fallback ID must be fresh 32 hex: %q (previous %q)", id, previousID)
}我最初在 handler 层的做法是按轮级键派生一个稳定值: convID = session.TurnRequestID("conv:" + turnKey)两者都能过渠道校验,差别在于:
如果上游的 需要说明的是:这一条我没有上游行为的直接证据,只是从字段命名和语义推断。 |
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 17, 2026
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 17, 2026
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 17, 2026
Closed
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 19, 2026
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 19, 2026
jin66god
pushed a commit
to jin66god/workbuddy2api-panel
that referenced
this pull request
Oct 19, 2026
pardSun
added a commit
to pardSun/workbuddy2api-panel
that referenced
this pull request
Oct 20, 2026
Owner
|
感谢实现。已由 #233(2d9e749)以更精确的形态合入:
你的核心痛点(健康账号被误判成封禁永久踢出)在分类层已根治。若后续实测发现 11140 也存在「申诉外自愈」的形态,欢迎单独开 issue 带证据讨论。多谢! |
zhf883680
pushed a commit
to zhf883680/workbuddy2api-panel
that referenced
this pull request
Oct 21, 2026
上游对渠道校验失败的响应是 HTTP 400 + {"code":"11-128","msg":"request illegal",
displayTips:{"zh":"渠道校验失败,可能不是从官方客户端发出的,请用官方客户端重新发送"}}——
它自述是「请求被拦截,请重新发送」,请求级可重试信号,不是账号级封禁。而我们的
applyErrorPolicy 在 ErrAccountFault 分支按 msg 字面量匹配 "request illegal" 就 Disable()
(理由写的是 11140 auth_forbidden),于是一个健康的号被永久踢出池子 + 要人工解冻。
**只取有证据那一半**:同一条 msg 骑两种 code,故按 code 分野——
- code "11-128"(字符串)→ 渠道校验拦截:CooldownSoftRate 软冷却,上游解除标记后自愈;
- code 11140(数字)→ auth_forbidden 账号级授权风控:保持硬禁用(软冷却只会反复送死);
- 14017 不变(本就走软冷却)。
判据复用 upstream 的 codeMarker(空白容差),新导出 HasCodeMarker 供 server 侧调用,
不把匹配口径散成两份。
线上证据(甲骨文):60 天 journal 里 "account banned by upstream" 0 次、11140/11-128 0 次,
当前 22 个号 0 个禁用——即本次是防御性收紧:错判的两个方向代价不对称(误禁用=永久丢号+
人工解冻;误软冷却=短暂轮换+退避自愈)。
测试:TestApplyErrorPolicyChannelVerificationKeepsAccount(11-128 → 未禁用 + soft_rate 冷却)、
TestApplyErrorPolicyAuthForbiddenStillDisables(11140 → 仍硬禁用);变异(11-128 又走硬禁用、
判据写成 11140)均红。
qcgzxw
added a commit
to qcgzxw/workbuddy2api-panel
that referenced
this pull request
Oct 21, 2026
…ools, never permanently disables)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
上游对「渠道校验失败」的响应是 HTTP 400,body 形如:
{"code":"11-128","msg":"request illegal","requestId":"...", "displayMsg":{"zh":"请求被拦截,请重新发送"}, "displayTips":{"zh":"渠道校验失败,可能不是从官方客户端发出的,请用官方客户端重新发送"}}上游自己的措辞是可重试的请求级拦截("请重新发送"),不是账号级封禁。
但
applyErrorPolicy在ErrAccountFault分支按 msg 字面量匹配request illegal,直接Pool.Disable():账号被永久踢出池子,且必须人工解冻才能恢复。这正是 #197 的现象。
为什么这是误判
用与网关完全相同的出站头部直连
https://www.workbuddy.ai/v2/chat/completions验证:400 11-128 request illegal200补充排除项,全部证明账号本身没问题:
exp到 2027-10,azp/aud与健康号完全一致global:deepseek-v4.1-flash/global:step-5-preview…)都同样 400 → 在模型解析之前就被拦X-Machine-ID/X-Session-ID、换随机 UUID、换 UA 平台段、加X-Device-Token、去掉X-No-Enterprise-Id、去掉全部X-IDE-*/X-Product归属头 —— 无一改变结果realm=global受影响,cn 号全部正常改动
request illegal从Disable改为软冷却:账号暂时出池、自动轮换,上游解除标记后自愈,不再需要人工解冻。
与 #190 的关系
触发这个 400 的根因是
X-Conversation-ID缺失,#190 已在internal/upstream/headers.go层修复,本 PR 不重复那部分。本 PR 是互补的防御面:即使将来上游换个措辞、或出现别的触发路径,误判的代价也从「账号永久禁用、必须人工解冻」降为「短暂轮换、自动恢复」。
验证
go build ./cmd/server、go vet ./internal/server/通过go test ./internal/server/ ./internal/upstream/通过Refs #190
Refs #197