Repository navigation
sys_metadata 不可用被 mapDataError 的 unknown-object 启发式误报成 404 OBJECT_NOT_FOUND,且 404 属「预期状态」因而一行日志都不留 #5462
Description
Activity
- addedbugSomething isn't workingSomething isn't working
on Aug 5, 2026 分诊(cli 车道 PM,
session_016FNvXhtSdnEGEfLEsMmvxh,2026-08-05):入队pm:queue,domain:cli。判级:真缺陷 —— 基础设施故障(sys_metadata 整体不可用)被looksLikeUnknownObject误分类成 404「对象不存在」,客户端读到错误结论,且 404 属isExpectedDataStatus连一行日志都不留 —— 双重静默,#5437 家族的启发式误判面(该单刻意不动启发式,本单正是收口处)。已在 #5464 的 harness 上实证复现。方向待派发时细化(启发式分类修正需读全部关键词分支再定,不预裁);基本约束先记:① 不带显式 status 的原始驱动错误不应被文本启发式升格为「预期 4xx」—— 误判方向宁可落 500 消毒(响亮 + 有日志)不可落 404 静默;② 修正后 #5464 的全部 pin 不得回归。
⛔ 串行约束(step 3 记录):与 PR #5464(#5437)同文件
rest-server.ts,须待其 MERGED 后基于新 main 派发,复用其 harness 与logWithheldServerFault。另 #5448(serve.ts)与本单不同文件可并行,#5447 在飞。
Generated by Claude Code
认领:PM 循环第 7 轮(cli 车道)
会话:session_016FNvXhtSdnEGEfLEsMmvxh
分支:claude/issue-5462-unknown-object-heuristic
Worktree:objectstack-issue-5462
域:domain:cli
文件面:packages/rest/src/rest-server.ts(mapDataError的looksLikeUnknownObject分支与isExpectedDataStatus日志口)+packages/rest测试(串行约束已解除:PR #5464 已 MERGED577cd27b;与在飞 #5224 的 meta/openapi 面同包不同函数区,文件面在rest-server.ts上相交 —— ⛔ 为避免同文件双在飞,本单暂缓派发,待 #5224 回报后串行)更正:认领评论发出即发现与 #5224 在
rest-server.ts相交,按 step 3 串行纪律本单不与 #5224 同批。保留认领与执行口径(13:1xZ 分诊评论),#5224 交付后派发。
Generated by Claude Code
派发解锁(cli 车道 PM,
session_016FNvXhtSdnEGEfLEsMmvxh,2026-08-05 15:1xZ):串行前提已全部落地 —— PR #5464(消毒 +logWithheldServerFault)与 PR #5487(meta/openapi 面收敛,rest-server.ts+176)均 MERGED。按 14:2xZ 认领评论的分支与口径即刻派发;基线以合并后origin/main(≥96d3d4d66)为准,dev 须同时核 #5464 与 #5487 两单落地后的mapDataError现状再动手。
Generated by Claude Code
ACCEPT → PR #5530。(PM 会话
session_016FNvXhtSdnEGEfLEsMmvxh,cli 车道)验收要点:
- 前提复核先行且成立——在 fix(rest): a declared 5xx no longer ships its own message to the client (#5437) #5464/fix(rest): 两个端点契约面只宣告匹配器实际会服务的集合 (#5224) #5487 都已落地的
origin/main上重跑复现,PUT /meta/object/acct仍 404OBJECT_NOT_FOUND+ 0 行日志,并顺手证明了逃逸错误status/code双缺,钉死了「fix(rest): a declared 5xx no longer ships its own message to the client (#5437) #5464 的显式 5xx 分支看不见它」这一本单成立的理由。 - 形状取舍服从实测:没有采纳我给的「驱动签名短路」备选——实测它会连坐真 unknown object(
SQLITE_ERROR:前缀同样出现在no such table: ghost上),破坏「真 404 不能变响」。改用归属判定(缺的 relation == 请求点名的对象才判 404),其正当性锚在 Prime Directive Migrate from npm to pnpm #6(对象名即表名,无映射可洗)。这与 sendError 的显式状态直通覆盖 400–599,5xx 的原始驱动报错绕过全部泄漏启发式直达客户端(metadata-protocol 有活体产出方) #5437 的先例同构:意图约束行为,机制服从实测。 - 不可归属一律落已有的消毒信封
500 DATABASE_ERROR(抽成一处DATA_STORE_FAULT(),与 SQL-leak 分支不再漂移),500 在isExpectedDataStatus之外,静默日志找回;引擎自撰分支与显式 status 带刻意不动;served-endpoints.ts未触碰(fix(rest): 两个端点契约面只宣告匹配器实际会服务的集合 (#5224) #5487 保护)。 - 反向验证方向先判后跑,还原旧启发式 9/21 红,红的正是误报 pin 与静默日志断言;对预判偏差(3 条同段用例本就该绿)如实申报而非改用例迁就模板——采纳这个处理。
- 全包 719 绿(合并 main 后复跑同绿),typecheck 不适用如实申报并跑了 [P2] framework: 66 个包用 tsup 构建、无人做类型检查 —— 实测 18 个包共 380 处 code-tier 错误(#4118 的 framework 侧对应) #4311 台账自己的闸门;消费半径扫描无跨包断言依赖旧判决。远程 CI 亲核 24 项 0 失败。
界外发现 #5532(producer 侧
getMetaItem裸catch吞 outage,本单归属规则够不到)已按规程无标签无指派落池,留给 triage 席。CI 已核,转 ready 挂 auto-merge,跟到 MERGED。
Generated by Claude Code
- 前提复核先行且成立——在 fix(rest): a declared 5xx no longer ships its own message to the client (#5437) #5464/fix(rest): 两个端点契约面只宣告匹配器实际会服务的集合 (#5224) #5487 都已落地的
- added a commit that references this issue
on Aug 6, 2026
做 #5437(
sendError5xx 直通消毒)时用真实 harness 打出来的旁证。不在那单范围内(那单只动resolveErrorResponse的显式 5xx 分支,⛔ 不动启发式本身),按 Prime Directive #10 单独记在这里,unassigned。现象
驱动层
sys_metadata整体不可用(表缺失/库不可达)时,一条不带status的原始驱动错误走到mapDataError,被looksLikeUnknownObject命中no such table,于是返回:客户端读到的是「你要的对象不存在」,真实情况是「元数据存储整体挂了」。这两件事的处置完全相反:前者让人去查对象名拼写,后者该去看运维。
更要紧的是日志侧:
isExpectedDataStatus把 404 列为正常客户端错误,handleRouteError因此不打[REST] Unhandled error。所以这条基础设施故障在服务端一行都不留。复现(in-process,已实跑)
真实
ObjectQL+ 真实ObjectStackProtocolImplementation,驱动的每个方法都抛SQLITE_ERROR: no such table: sys_metadata:Postgres 措辞(
relation "sys_metadata" does not exist)同样命中looksLikeUnknownObject的第二条分支,结果一致。成因
packages/rest/src/rest-server.ts的looksLikeUnknownObject只看消息文本里有没有no such table/relation ... does not exist,不区分缺的是哪张表。业务对象的表缺失和sys_metadata缺失是同一条正则的两个命中,但语义相反:前者确实约等于「对象没注册」,后者是元数据平面自身故障。注意 #5437 只把显式声明了 5xx 的错误挡在启发式之前;这条路径上的错误不带
status,因此仍然整条走mapDataError,不受 #5437 影响。可选方向(不代裁决)
looksLikeUnknownObject对sys_metadata之类系统表名的命中单独判为 5xx(基础设施故障),不复用OBJECT_NOT_FOUND信封。status: 500(落地 sendError 的显式状态直通覆盖 400–599,5xx 的原始驱动报错绕过全部泄漏启发式直达客户端(metadata-protocol 有活体产出方) #5437 后即自动获得消毒 + 日志)。isExpectedDataStatus的 404 豁免只在code === 'OBJECT_NOT_FOUND'且消息不含系统表名时成立。未验证的部分
只打了
PUT/DELETE /api/v1/meta/:type/:name两条路由;数据路由(/api/v1/data/*)在sys_metadata挂掉时的表现没测。是否有别的系统表(sys_environment等)落进同一条启发式也没清点。关联
#5437(发现于此;只覆盖显式 5xx 一侧)、#3867(消毒器)、#4886(
isExpectedDataStatus/ 日志判定)、#3770(OBJECT_NOT_FOUND单一信封)。Generated by Claude Code