Repository navigation
Description
做 #5048(PR #5572)时在同包扫到的同类形态,按 Prime Directive #10 单开,不在那个 PR 里扩面。
现象
AutomationServicePlugin.materializeDeclaredConnectors 的报错器(packages/services/service-automation/src/plugin.ts:1039)在软路径上把消息字符串交给 logger:
// Report a reconcile problem: fatal (boot) throws; soft (reload) logs.
const fail = (msg: string): void => {
if (opts.fatal) throw new Error(msg);
ctx.logger.error(msg);
};而两个调用点把底层错误的 message 插进那个字符串:
plugin.ts:1122—resolveInstanceAuth失败:fail((err as Error).message)plugin.ts:1158-1161— provider factory 抛错:fail(`[Automation] failed to materialize connector instance '${name}' via provider '${provider}': ${(err as Error).message} (ADR-0097).`)
这与 #5048 修掉的形态一模一样:err.message 一旦是多行(ZodError 的 .message 是 issue 数组的 JSON dump,第一行就是一个 [),ObjectLogger.write() 只有第一行带等级前缀,而 serve 的 BootLogCapture.offer() 逐行过滤、把没有前缀的续行全部丢弃 —— 诊断退化成一个 [。
fatal: true 那条路(冷启动)不受影响:它 throw,走 kernel 的失败通道,不经过启动诊断缓冲。受影响的是软路径,即 metadata:reloaded 之后的重新物化 —— 也就是 Studio publish / os dev 重编译之后。
可达性:今天大概到不了,所以是 finding
我查过 packages/connectors/*/src(openapi / mcp / rest / slack),目前没有 provider factory 做 Zod .parse()(只有 openapi 的一处 JSON.parse),所以今天从 factory 抛出 ZodError 的路径我没能证明存在。resolveInstanceAuth 那条也没查到 Zod 解析。
但这个形态的风险不需要 ZodError 才成立:任何多行 err.message 都会被同一台管线截断,而 ADR-0097 明确鼓励第三方写 provider factory —— 第一个在 factory 里用 Zod 校验 providerConfig 的插件(这是很自然的写法)就会撞上。而且撞上时的症状和 cloud#971 一样:症状不可读,所以缺陷得以隐身。
建议的修法
与 PR #5572 同一原则,复用它落地的 helper:
const fail = (msg: string, cause?: unknown): void => {
if (opts.fatal) throw new Error(msg);
ctx.logger.error(msg, cause === undefined ? undefined : describeFlowBindError(cause));
};(describeFlowBindError 在 packages/services/service-automation/src/flow-bind-diagnostics.ts,PR #5572 引入;若要给 connector 复用,名字值得从 FlowBind* 泛化成 describeThrownForLog 一类,那是这单要顺带定的一个小决定。注意 Logger.error 的签名是 error(message, error?: Error, meta?) —— 第二参是 Error 不是 meta,ObjectLogger.error 在运行时对二者都做了分派,但类型上要走 meta 就得确认契约,不能想当然。)
影响面
- 可诊断性缺陷,同 bug(service-automation): flow 绑定失败的告警把 Zod issue 数组塞进单行日志,读者只拿到一个孤零零的
[#5048 的类别、另一个接缝;触发条件是软路径(reload 后重新物化)上err.message恰好多行。 - 位置:
packages/services/service-automation/src/plugin.ts:1039(fail)、:1122、:1158-1161。 - 关联:bug(service-automation): flow 绑定失败的告警把 Zod issue 数组塞进单行日志,读者只拿到一个孤零零的
[#5048 / PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572(同类,已修 flow 绑定那四+一处)、[convention] best-effort 降级导致"看起来正常、实则不持久"时不应记 warn——把 #4460 的点状修复定成规则 #4632(被截断的诊断比没有诊断更贵)、ADR-0097。
Generated by Claude Code
Activity
os-zhuang commentedon Aug 5, 2026
发现分诊轮判级:晋级 —— 摘
finding换pm:queue(domain:services已在)。[#5048(PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572)今日已合入 main,模式既定(结构化 log meta 替代单行err.message插值);落点已核实 ——packages/services/service-automation/src/plugin.ts:1122的fail((err as Error).message)在 fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572 之后仍在,属同类别另一接缝的机械跟进,无待裁问题。[#5048 同文件;services 车道若另有在飞单触plugin.ts,按同文件跨轮串行。本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
认领(services 车道 PM 派发,
session_01BWS4heBoAitLmzCLhcYdbK)claude/issue-5575-connector-fail-cause../objectstack-issue-5575(dev 子代理按 worktree-first 自建)packages/services/service-automation/src/plugin.ts(fail():1039 + 两调用点 :1122 / :1158-1161)、src/flow-bind-diagnostics.ts(helper 复用/泛化命名)、同包测试、.changeset/*.md。[#5048(PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572)与同包 嵌入式 host 直接 new AutomationEngine() 而不调用 sealNodeTypeVocabulary(),就完全拿不到节点类型校验 —— #4771 的连带回退,靠文档而非强制 #4792(PR fix(service-automation): 从未 seal 的引擎首次执行 flow 时告警一次 (#4792) #5595)均已 merged,service-automation 当前无在飞 PR;同包在飞的 analytics 的string[]值往返对字符串比较数也有损:{code: {$eq: '007'}}绑成数字7、'null'绑成真 NULL、'true'绑成1—— 文本列静默取到错行 #5526 在 service-analytics,不相交。Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
认领文件面修正(services 车道 PM,
session_01BWS4uuidHfQkPYt6dQzWpg笔误更正:session_01BWS4heBoAitLmzCLhcYdbK)PR #5639 的实际文件面超出认领时申报的范围,补记如下,责任在 PM 派发时未预见(与 #3823 那次同型,提前自报):
packages/core/src/logger.ts+packages/core/src/__tests__/logger.test.ts—— dev 实现时发现按Logger契约(packages/spec/src/contracts/logger.ts:37)的(msg, undefined, meta)形状在ObjectLogger里是死路(第三参从未被读取,契约另两个实现 ConsoleLogger/JsonLogger 均正确),本单的结构化 meta 修法依赖该参数生效 —— 属 PD chore: version packages #10「declared ≠ enforced」的实现缺陷,修生产者而非在消费端将就(PD Add comprehensive test suite for Zod schema validation #12)。契约文件未动,无公开面变化。flow-bind-diagnostics.ts→thrown-cause-diagnostics.ts(包内符号,授权范围内的既定小决定)。packages/core按 docs(pm-dispatch): 协调模型改版 —— 分诊/执行纵向拆分 + 一人一车道双射 + 登记表正文即真相 + 座位 Routine 化 (#5472) #5522 域表归 engine-core。已核对该车道当前无在飞 PR 触logger.ts(finding(core): ObjectLogger 的脱敏表按子串匹配,一个叫keys的普通字段会被整块换成***REDACTED***#5573 持有中无 PR、finding(objectql): registerReapGuard 后注册者静默顶掉前者,且注册表私有 —— 第二个注册方察觉不到自己解除了别人的 guard #5535 在 lifecycle-service.ts);消费半径(metadata / metadata-protocol / client)已由 dev 全量回归。若 engine-core 座位对 logger.ts 的这次收敛有异议,以其复核为准。Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
PM 复核:ACCEPT — PR #5639(session_01BWS4heBoAitLmzCLhcYdbK 车道)
逐项核对 dev 报告与 PR:
serve.ts:713注释自证;软路径在restoreOutput()之后)—— 修复理由按真实机制(stderr 按行消费者无法归属续行)重写,没有沿用响亮但不成立的说法。真正命中 BootLogCapture 的第三接缝已另立 finding(service-automation): connector 降级路径(#3017)还有两处${err.message}单行插值,是 #5575 之外的第三个接缝 #5636 且标注严重度更高。meta在ObjectLogger是死路(实测{"msg":"A"},~15 处按契约写的调用点全在丢诊断,ConsoleLogger/JsonLogger 均正确)—— 修生产者收敛到契约,契约文件未动、无公开面变化;放宽契约的反向方案否决理由充分。文件面超出认领申报的部分已由 PM 在上方补记并向 engine-core 座位标记。thrown-cause-diagnostics.ts)在授权范围内,包内封闭性已核(index.ts 未导出、包外零引用);fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572 的unrecognized命名与截断申报模式保留。HTTP request failed记录恢复携带结构化字段属预期正向变化。fatal 路径三处无 cause 报告字节不变、4 条既有.toThrow断言零改动 —— 行为面收窄到精确。${err.message}单行插值,是 #5575 之外的第三个接缝 #5636 / finding(objectql): hook 层自带的 logger 接口把error声明成(msg, meta?),与Logger契约的第二参是Error相反 —— 三处调用点在任何忠于契约的 Logger 下都会丢掉 meta #5637 均 observation-class、unassigned、留分诊座位;authorable-surface.base.json副作用每次还原未进提交(与check:authorable-surface在--check模式下也会重写authorable-surface.base.json—— 一次纯核验会改工作区,且任何无关 PR 都能因此静默推进删除门的锚点 #5358/os-regen 驱动指示的gen:schema在 merge 未 commit 时运行,会把 authorable-surface 锚点倒退回旧 merge-base —— 生成器写入、门全绿、静默撤销 main 的锚点推进 #5370 同族,PM 已查重确认不另立单)。处置:CI 全绿后转 ready 并开 auto-merge 进队。
Generated by Claude Code
fix(service-automation): connector reconcile reports its cause struct…
fix(service-automation): connector 降级路径的两条日志改用结构化 meta (objectstack-a…
fix(service-automation): 启动路径三条日志的外来 cause 改走结构化 meta (objectstack-ai…
fix(service-automation): the degrade REGISTRATION logs its cause as m…