Skip to content

[17.0-rc][疑似平台] 全局(无 objectName)action 无法派发,且 UI 把失败当成功静默吞掉 #522

Closed

Description

@yinlianghui

现象

17.0.0-rc.0 下,全局 action(log_call / log_meeting / export_csv)执行后什么都没发生:弹窗关闭、无提示、无数据写入。

复现

POST /api/v1/actions/crm_case/log_call 返回 HTTP 200,响应体:

{"success":true,"data":{"success":false,"error":"Action 'log_call' on object '*' not found"}}

export_csv 同样。flow 型 action 走该端点也报同样错误(错误信息有误导性)。

两个问题:

  1. 无 objectName 的 action 在 17.0 注册/派发失效("not found on object '*'")
  2. 外层 success:true 包内层失败,控制台按成功处理,用户完全无感知

影响

所有全局 action 均不可用且静默失败。升级阻断。

详见分支 upgrade/objectstack-17 的 docs/upgrade-17/test-report.md §3 P3。

Activity

  1. yinlianghui commented on Jul 29, 2026

    @yinlianghui
    CollaboratorAuthor

    源码确认:CONFIRMED,平台 bug ×2。注册键 'global'(app-plugin.ts:640-644)vs REST 回退查找键 '*'(domains/actions.ts:195-204),引擎精确匹配无通配(engine.ts:731-746)——POST /api/v1/actions/global/ 反而能通(意外命中注册键)。所有 handler 失败经 deps.success() 包成 HTTP 200(domains/actions.ts:215 → http-dispatcher.ts:444)。已上报平台:objectstack-ai/objectstack#3913;console 只查外层信封的 UI 半边:objectstack-ai/objectui#2958

  2. yinlianghui commented on Jul 29, 2026

    @yinlianghui
    CollaboratorAuthor

    📎 分支 upgrade/objectstack-17 已推送至上游(仅分支,无 PR,勿合并——阻塞于 17.0 正式版与 objectstack#3912/#3913/#3914)。正文引用的文档现在可直接访问:测试报告 | 测试计划

  3. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    rc.2 retest: 已解除 — dispatch resolves, failures are non-200, and the UI no longer swallows errors

    Retested on @objectstack/* 17.0.0-rc.2 (current main), full action sweep.

    Dispatch half:

    • HotCRM no longer ships objectless actions — Activity model: first-class meetings/events + call logging on every sales object #592 generates log_call/log_meeting/schedule_meeting per object. The rc.0 broken path POST /api/v1/actions/crm_case/log_call now returns 200 with real writes: crm_event + sys_activity + crm_event_attendee rows all verified. All 15 activity-action combinations pass.
    • POST /api/v1/actions/global/log_call → clean 404 RESOURCE_NOT_FOUND with an actionable governance message ("Action 'log_call' on 'global' has no declaration — … ADR-0110 D3"). The 'global'-vs-'*' registry mismatch ghost is gone.

    Envelope half:

    • Script-body failures now return HTTP 400 (VALIDATION_ERROR) and unknown actions 404 — no more HTTP 200 {"success":false} on the /actions path. The console shows red error toasts; the rc.0 silent dialog-close was explicitly probed for and not reproduced.
    • Residue: the flow resume path (/api/v1/automation/*/runs/*/resume) still 200-wraps inner failure ({"success":true,"data":{"success":false,…}}), but the console now reads the inner envelope and surfaces the node error verbatim (verified with an engineered server-side failure — see the [17.0-rc][疑似平台] flow 型 action 菜单项无响应;screen flow 服务端失败无任何 UI 回显 #524 comment). So the user-facing symptom is resolved; the wire shape on that one path is the remaining upstream cosmetic.

    Upstream objectstack#3913 confirmed fixed for the paths this issue covered. Recommend closing after owner confirmation; if anyone wants to chase the automation-path envelope shape, that's a new, much smaller upstream ticket.


    Generated by Claude Code

  4. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    CollaboratorAuthor

    [17.0-rc2验收复核] 结论:已不复现(派发与信封两半均解除;automation resume 路径残留一处 200 包裹但已不误导)

    证据:独立 dev server(端口 4091,全新种子库)实测:

    派发半

    信封半

    环境:hotcrm@0899b4f + @objectstack 17.0.0-rc.2

    建议:前提已过时建议关闭(与 #509 同批);resume 路径的信封形状若要追,单开小上游单即可,不必留本单。


    Generated by Claude Code

  5. huangyiirene commented on Aug 11, 2026

    @huangyiirene
    Collaborator

    Re-measured on @objectstack/* 17.0.0-rc.6 during the rc.5 → rc.6 upgrade (#1059, PR #1066). Problem 1 (dispatch) has explicit machinery now; problem 2 (the UI swallowing the failure) was not probed.

    @objectstack/objectql now carries a dedicated action-governance path for object-less actions:

    var GLOBAL_ACTION_OBJECT_KEY = "global";
    function isObjectLessActionKey(objectName) {
      return !objectName || objectName === GLOBAL_ACTION_OBJECT_KEY || objectName === "*";
    }
    function actionHandlerObjectKeys(objectName) {
      return [objectName, GLOBAL_ACTION_OBJECT_KEY, "*"].filter((k, i, all) => all.indexOf(k) === i);
    }

    Two things follow. An action with no objectName, one keyed "global", and one keyed "*" are now treated as the same thing — the ambiguity behind Action 'log_call' on object '*' not found. And handler resolution walks a key list rather than a single key, so a global action registered under one spelling is found when dispatched under another. There is a reconcileActionRegistrations pass in the same module, so registration is reconciled rather than assumed.

    Problem 2 is untouched by this measurement. The {"success":true,"data":{"success":false,"error":"…"}} envelope — outer success wrapping inner failure, which the console reads as success and shows the user nothing — is a REST/console concern, and I did not probe it. It is also the more dangerous half: it is what turned a dispatch bug into a silent one, and it would hide the next dispatch failure just as well. #524 makes the same complaint from the screen-flow side, so the two probably close together.

    Scope note: static read of the shipped engine, not a live POST /api/v1/actions/crm_case/log_call. Before closing, that call and an export_csv run should be re-measured against a booted rc.6 server — the response envelope is the thing to watch, not just the status code.


    Generated by Claude Code

  6. hotlong commented on Aug 14, 2026

    @hotlong
    Contributor

    Transfer sweep (#1156, part 1) — outcome 3: fixed upstream, no longer reproduces. Closing with the reading.

    The outcome test that was applied

    Where would the fix land today? Nowhere — there is no defect left to fix. Both of this card's two stated problems were fixed on the platform side and independently re-measured. Per #1156, a defect that is gone gets no upstream card; closing on the reading is the whole disposition.

    The reading, both halves

    This card raised exactly two problems. Both are resolved.

    Problem 1 — object-less action dispatch fails (Action 'log_call' on object '*' not found). The root cause was a registry-key mismatch: registration under 'global' versus REST fallback lookup under '*', with exact matching and no wildcard. On rc.6 the engine carries dedicated governance for this: GLOBAL_ACTION_OBJECT_KEY, an isObjectLessActionKey predicate treating absent / 'global' / '*' as the same thing, and actionHandlerObjectKeys resolving against a key list rather than a single key, plus a reconcileActionRegistrations pass. Measured live on rc.2: POST /api/v1/actions/crm_case/log_call returns 200 with real writes (crm_event + sys_activity + crm_event_attendee rows all verified, all 15 activity-action combinations passing), and POST /api/v1/actions/global/log_call returns a clean 404 RESOURCE_NOT_FOUND with an actionable governance message. The ghost is gone.

    Problem 2 — outer success:true wrapping inner failure, swallowed silently by the console. On the /actions path this is gone: script-body failures now return HTTP 400 VALIDATION_ERROR and unknown actions 404. No more HTTP 200 {"success":false}. The console shows red error toasts; the rc.0 silent dialog-close was explicitly probed for and not reproduced.

    Upstream objectstack#3913 is confirmed fixed for the paths this card covered.

    Why this is safe to close, given #1156's warning about this repo's account-book

    #1156 warns that three of eight "verified fixed" cards did not survive re-reading, so a single on-card "recommends closing" is not enough. This card has four independent readings that agree, taken by different seats with different methods:

    1. rc.2 full action sweep (browser + writes verified end to end);
    2. rc.2 independent dev server, port 4091, fresh seed DB, pure API;
    3. rc.6 static read of the shipped @objectstack/objectql governance path;
    4. this sweep's read of the upstream mirror's state.

    Two of them explicitly recommended closing and nobody executed it. That is the opposite of the failure mode #1156 describes — this is an unexecuted close, not an unverified claim.

    The one residue, and where it went — so it is not dropped

    This card's rc.2 review recorded a leftover: the automation resume path (/api/v1/automation/*/runs/*/resume) still answers HTTP 200 while wrapping an inner {success:false}. That is not one of this card's two problems — the console reads the inner envelope and surfaces the node error verbatim, so the user-visible symptom this card was filed about is resolved — but it is a live wire-contract inconsistency, and both readings that noted it said it deserved its own small upstream ticket.

    It was being held by two cards, and both are now closed: this one, and #524 (closed 2026-08-14), whose closing record parks the residue here. With both closed it would have had no holder at all.

    ⇒ Filed fresh upstream: objectstack-ai/objectstack#8684. It carries the measured request/response, the contrast with objectstack#3962 (which unified /actions on real status codes before GA and is closed), an honest statement that impact is bounded to scripted callers, and the note that the readings are rc.2-era and need re-measuring on GA. No labels applied and no release target nominated, per #1156.

    Labels: left as they are, deliberately

    upstream:objectstack stays on this card. Unlike #700 and #510 — where the label turned out to be wrong and was removed — here it was right: this was a genuine platform defect, it was routed upstream, and the platform fixed it. Stripping it would erase accurate history on a closed card. prio:p1 likewise records what this was at the time (an upgrade blocker), not a claim about today.

    What was NOT done here

    No app boot, no probe, no GA re-measurement. This sweep is routing and bookkeeping only. Every measurement quoted above is an existing on-card reading taken by another seat on rc.2 / rc.6; what this sweep added is the upstream-state verification and the residue's new home. If 17.0.0 GA behaviour has regressed against these readings, reopen — the four readings above are the regression hooks.

    Authority

    hotcrm 席位的原则是用平台的能力做元数据应用的开发,平台的需求应该转给平台

    The platform need this card carried was routed and met. The companion disposition 「关掉,只留指向镜像的指针」 is satisfied by the pointers above: objectstack#3913 for what was fixed, and objectstack#8684 for the residue that outlived it.


    Generated by Claude Code


    Generated by Claude Code

  7. added
    priority:p1High: required for production / M2
    and removed on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p1High: required for production / M2upstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions