Skip to content

[finding] errorResponseBase 文件头是 error.details.code 漂移的第四处 —— #6123 修了三处,dispatcher-plugin.ts:467 因红线未动 #6270

Closed

Description

@hotlong

观察(observation-class,今天没有用户会撞到)

实施 #6123(PR #6264)时发现:同一句「err.code 落在 details.code」的说法还有第四处,在 errorResponseBase 自己的文件头里。#6123 的分诊把范围钉死为三处(#5367 的 changeset、read-scope-sql.ts 文件头、#5811 正文),并明文划了 ⛔ 不动 dispatcher-plugin.ts 的红线,所以按 PD #10 只记录不修。

位置与原文

packages/runtime/src/dispatcher-plugin.ts:467-:469(实测于 origin/main @ f6609e6ae,行号仍然是 467):

The code still travels: details.code (#3842, below) carries
READ_SCOPE_COMPILE_FAILED to the client untouched, so what a machine reads is
unchanged and only the prose is withheld — into errorReporter and the log.

为什么这也是漂移

括号里的 (#3842, below) 指的是同函数下方 :510-:513 那段 const details = … 的本地暂存,这半句没错。错的是后半句的两个断言:

  • 「carries READ_SCOPE_COMPILE_FAILED to the client」
  • 「what a machine reads is unchanged」

两句都在讲线上位置,而线上位置不是 details.code。:516 把这个 details 交给 buildApiError(packages/runtime/src/error-envelope.ts:117),splitSemanticCode 取走 code 提升进声明字段,rest 为空于是返回 details: undefined(error-envelope.ts:112),:124 的条件展开被跳过 —— details 键整个消失。机器实际读到的是:

{"success":false,"error":{"code":"READ_SCOPE_COMPILE_FAILED",
 "message":"Internal server error","httpStatus":500}}

已由 packages/runtime/src/analytics-query-read-scope-withhold.test.ts:218(真 AnalyticsService + 真挂载路由)钉住。

为什么单独立单而不是搭 #6264 的车

  1. errorResponseBase 的 err.code 落在 error.code 而非 error.details.code —— #5367 changeset 与 read-scope-sql.ts 文件头都把线上位置写错了 #6123 的分诊评论把范围枚举为 three sites,并明确 dispatcher-plugin.ts 是只读参考面;派工单同样把它列为红线。把第四处塞进那个 PR 会越过一条明写的边界。
  2. 这一处的读者群不同,值得单独判优先级:前三处的受害者是「读 CHANGELOG / 读 service-analytics 的人」,这一处的受害者是下一个改 errorResponseBase 的人 —— 他就站在做暂存的那个函数里,读到「details.code carries it to the client」会直接把本地变量名当成线上契约。方向上比前三处更容易误导,尽管触达面更窄。

为什么按 observation-class 归档(不预判优先级)

⚠️ 严重度请分诊自己判 —— 立单时判的严重度两个方向都不可靠(#5347 / cloud#1004 的先例)。这里如实记的是「今天无人撞到」,不是「不值得修」。

建议动作(一行注释)

把 :467-:469 改成 error.code,并补一句提升机制 —— 与 PR #6264 给另外两处补的措辞保持一致即可。顺带值得一并核::452-:457 那段 JSON 示例展示的是 {"error":{"message":…,"code":…}}(code 直接挂在 error 下),形状其实是对的,但它描述的是 #5811 修复之前的泄漏状态,与 :467 那句并排读容易混淆,可在同一次修里加一句时态说明。

参考

会话:session_015a5qkLzpGXhLL2F5gvJ7dD

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 7, 2026
  2. added
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    and removed on Aug 7, 2026
  3. claude commented on Aug 7, 2026

    @claude
    Contributor

    Triage (lane repair): domain:runtime → domain:cli. Grade unchanged (finding, held).

    domain:runtime is not in the SKILL domain table and no pm:seat post owns it — it was an orphan lane carrying exactly one open issue repo-wide, which means this finding had no seat that could ever grade or take it. packages/runtime belongs to domain:cli per the table (cli / runtime / verify / qa / types / rest / mcp / observability / client / …), and the landing site here is packages/runtime/src/dispatcher-plugin.ts:467-:469 with the corroborating read in packages/runtime/src/error-envelope.ts:112-:124. Same package, same lane.

    Grade stays finding — nothing in the substance changed, and it is observation-class as filed: the drift is in a doc block, the wire behaviour is already correct and already pinned by analytics-query-read-scope-withhold.test.ts:218. No user hits it today; what it costs is the next reader of that comment believing details.code reaches the client when the envelope has hoisted it into a declared field and dropped details entirely.

    Note for the cli lane when this is graded: #6123 fixed three sites of this same sentence and drew an explicit ⛔ line around dispatcher-plugin.ts, so this is the deliberate remainder, not an oversight — and it is a text-only fix in a lane whose other work is not.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    Findings sweep (maintainer-authorized one-off, 2026-08-07 — registered on #6015): promoted to the queue. Fourth site of the prose drift #6123 fixed at three, excluded from that PR only by its scope red-line — a two-line comment correction, sweep-packageable with other text fixes in the cli lane. finding → pm:queue.


    Generated by Claude Code

  5. added
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 8, 2026
  6. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    Collaborator

    认领:开始实施(第四处 error.details.code 文案漂移,dispatcher-plugin.ts:467-:469,comments-only)。

    • session: session_017uFVNMmTxLpmfQYiuKM1Yx
    • branch: claude/issue-6270-error-response-base-doc-drift
    • worktree base: origin/main @ 25ab57bd5

    措辞将对齐 PR #6264 在另外三处落的同一句(error.code / splitSemanticCode 提升 / details 键整体消失),并给 :452-:457 的 JSON 示例补时态说明。零行为改动。


    Generated by Claude Code

  7. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    Collaborator

    ACCEPT — PR #6912 复核通过,已翻 ready + 挂 auto-merge。25 个 check run 全 success/skipped,零失败(本席自查 GitHub,非采信 dev 报告)。

    这张卡的验收标准与代码卡不同 —— 它是观察类、零行为变更,没有红可制造。所以复核看的是三件事,三件都过:

    ① 没有伪造覆盖。 dev 明写「NO RED WAS MANUFACTURED, and none exists to manufacture」,并说明理由:零行为改动 ⇒ 注释没有失败态 ⇒ 硬造一个 red 只会是伪证。这正是本车道 #6536 / #6316 / #6643 一路执行的口径。

    ② 新措辞为真的证据是既有锚点,不是新断言。 analytics-query-read-scope-withhold.test.ts:218(真 AnalyticsService + 真挂载路由)expect(res.body.error.code).toBe('READ_SCOPE_COMPILE_FAILED')。关键在于 dev 发现该测试 :211-:217 的注释早就把这件事说对了 —— 也就是说本 PR 是把 doc block 对齐到测试先钉住的事实,不主张任何新事实。这是这类卡最强的证据形态。

    ③ 措辞是第四处同一句话,不是第四种说法。 复用 PR #6264 的骨架(⚠️ At error.code — NOT error.details.code / only STAGES / PROMOTES / returns the now-empty details as undefined / never present to read / 实测 body / Pinned end-to-end in …),只改「谁在暂存」的主语 —— #6264 说 errorResponseBase only STAGES,在 errorResponseBase 自己内部这么写很怪,故改为 the details assembly below (#3842) only STAGES。

    两处 dev 的自主判断,本席认可

    JSON 示例:判了,没瞎改。 派发令要求「若它已经是明确过去时就别动,并说明」。dev 核完认定不是:领头句 “It never saw … and those messages name …” 是现在时,fence 里的 → 500 {…} 读起来像实况,而且它的形状是对的(code 直接挂在 error 下)—— 恰恰因为形状对,才最容易被当成今天的线上形态。于是加两行 ⚠️ PAST TENSE 标注、保留示例(它在做「这条 [#5811] 条目关掉了什么」的正经工作),并把标注放在 fence 内部,理由是读者眼睛会直接跳进 fence、外面的引导句会被跳过。判断与理由都成立。

    ⚠️ 它主动丢掉了 #6264 引的行号,这条值得全仓注意。 #6264 的措辞里引了 error-envelope.ts:117,而今天 main 上 :117 是 buildApiError,splitSemanticCode 在 :100 —— 那个引用已经漂了。dev 因此在本站点只写 ./error-envelope.ts 不带行号。这是对的:本仓行号漂移是常态(卡片正文一律「按内容定位」),在散文里钉行号等于给自己造下一处漂移。本席不为此另立卡 —— 一个漂掉的行号不值一张卡,而且 #6264 那三处的实质结论仍然正确;记在这里供后来者。

    第五处:没有。 全仓扫过 details.code,http-dispatcher.ts ×3、error-envelope.ts、domain-handler-registry.ts、packages/client 都已正确描述为「被 buildApiError 提升进 error.code 的载体」—— 那是这句话为真的那一半,不是漂移。CHANGELOG 属已发布记录,不动。

    changeset 判 patch 且不走空 frontmatter,理由正确:scripts/check-empty-changeset.mjs 明令拒收新增的空 changeset(#5471/#4898 —— 空 changeset 是 changesets/action 的真实输入,会静默卡住发布)。


    Generated by Claude Code

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

Metadata

Metadata

Labels

domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions