Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console: 零应用下 sys-objects / sys-datasources 落到 /apps/setup/component/... 渲染空白屏——无-activeApp 分支既无 component/* 路由也无 catch-all #3610

Closed

Description

@yinlianghui

越界发现,记录于 #3590(改三处 sys-settings 的目标 URL)期间。按纪律只报不改,单独立单,未认领,留给 PM 分诊。

实测基线:origin/main @ 03f25f7a3。

现象

零应用部署下,系统兜底导航里的两项点下去是纯白屏(不是空态、不是 404、没有任何报错):

  • sys-datasources → /apps/setup/component/metadata/resource?type=datasource
  • sys-objects → /apps/setup/system/metadata/object(先被重定向,落点同上)

实测链路

packages/app-shell/src/console/AppContent.tsx(行号为 03f25f7a3):

  1. 185 行 isMetadataRoute = location.pathname.includes('/metadata') —— /apps/setup/component/metadata/resource 含 /metadata,为真。
  2. 于是 568 行的空态守卫被跳过,落进 604 行 !activeApp && (isCreateAppRoute || isSystemRoute || isMetadataRoute) 分支。
  3. 该分支的 Routes 只声明了:create-app、system/marketplace*、metadata、metadata/_diagnostics、metadata/:type[/…],外加宿主传入的 extraRoutesNoApp(console 的 systemRoutes:system/*、developer/*、docs/*)。
  4. 相对路径 component/metadata/resource 一个都不匹配;该分支没有 catch-all(对比:有 activeApp 的分支末尾有 path="*" → RouteNotFound)。Routes 渲染 null ⇒ 白屏。

sys-objects 走的是同一个坑,只是多绕一步:/apps/setup/system/metadata/object 命中 apps/console/src/AppContent.tsx 的 system/metadata/:metadataType → MetadataRedirect,后者把 URL 改写成 ${prefix}/component/metadata/resource?type=object,prefix 即 /apps/setup —— 于是落回上面那条白屏路径。

两个调用点

两处 sys-* 簇都带这两项(行号为 origin/main @ 03f25f7a3):

packages/app-shell/src/layout/AppSidebar.tsx:320     sys-objects      -> /apps/setup/system/metadata/object
packages/app-shell/src/layout/AppSidebar.tsx:321     sys-datasources  -> /apps/setup/component/metadata/resource?type=datasource
packages/app-shell/src/layout/UnifiedSidebar.tsx:325  sys-objects      同上
packages/app-shell/src/layout/UnifiedSidebar.tsx:326  sys-datasources  同上

AppSidebar 那份只在零应用时渲染(systemFallbackNavigation),所以它命中的正是本单场景。UnifiedSidebar 那份目前整簇渲染不出来(另见 #3609)。

影响

零应用部署的管理员从系统兜底侧栏点「Object Manager」或「Datasources」,得到一块白屏 —— 没有 404、没有提示,看起来像应用崩了。全新环境要建第一个对象,这两项恰恰是必经之路。

可能的修法(留给分诊)

两个方向互不排斥,值得一起定:

  1. 给无-activeApp 分支补 catch-all(path="*" → RouteNotFound)—— 白屏至少变成可读的「没找到」。这是止血,不是根治。
  2. 让 component/* 在无 activeApp 时可达,或把这两项的 URL 改到该分支已声明的 metadata/:type 形态上 —— 后者要先确认 metadata/:type 与 component/metadata/resource?type= 是不是同一个页面的两种拼法(MetadataRedirect 的存在暗示前者是旧链)。

⚠️ 按 #0.1 契约优先:若结论是「component/metadata/resource 才是规范拼法」,那修法应是让路由分支支持它,而不是在导航侧写一个只在零应用时生效的别名。

关联

已就关键词(component/metadata/resource / isMetadataRoute / extraRoutesNoApp / 空白屏 / catch-all)搜过三仓开放 issue 与 PR,无同源单。

Activity

  1. claude commented on Aug 7, 2026

    @claude
    Contributor

    Triage: pm:queue — white screen confirmed live; ⚠️ line numbers drifted

    Verdict. Queued. No domain:* (objectui is a whole-repo seat). A blank render with no error, no 404 and no empty state is the worst diagnosable class of navigation bug, and the trace you gave makes it a one-sitting fix.

    Premise re-verified against origin/main @ 616353a (your baseline 03f25f7a3 predates #3590's merge, so coordinates moved):

    • AppSidebar.tsx:320/321 → now :329 / :330; both targets unchanged — sys-objects → /apps/setup/system/metadata/object, sys-datasources → /apps/setup/component/metadata/resource?type=datasource.
    • AppContent.tsx:185 isMetadataRoute = pathname.includes('/metadata') → now :185 region, logic unchanged; /apps/setup/component/metadata/resource still matches it.
    • The decisive check: path="*" appears exactly once in AppContent.tsx (:775), in the activeApp branch. The no-activeApp branch still has no catch-all, so an unmatched relative path still renders null. Both halves of your two-part cause are intact.

    Why the fix needs both halves, and the card should not be split. The includes('/metadata') substring test is what steers the request past the empty-state guard into a branch that cannot serve it; the missing catch-all is what turns "no route matched" into a blank page instead of RouteNotFound. Correcting only the two sidebar URLs leaves the branch silently blank for the next unmatched path; adding only the catch-all converts a white screen into a 404 for a destination the user was legitimately sent to. Land both: the catch-all is the general fix and the URL correction is the specific one, and the catch-all is what makes the next occurrence of this class reportable rather than invisible.

    sys-objects reaching the same dead end via MetadataRedirect (rewriting to ${prefix}/component/metadata/resource?type=object) is worth a test pin — it is the non-obvious half and would regress silently.

    Sequencing (not a blocker). #3611 also edits AppSidebar.tsx (:454 / :684). Different lines, same hot file — ⛔ not concurrent independent claims. #3609 is the third member of this zero-app console cluster but touches UnifiedSidebar.tsx, so it is file-disjoint from both.

    Dedup (issues + PRs, three repos): no duplicate; #3590 is the closed parent, this is declared remainder.

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


    Generated by Claude Code

  2. self-assigned this
    on Aug 7, 2026
  3. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    认领(PM 派发)。


    Generated by Claude Code

  4. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    验收 ACCEPT → PR #3636(session_01GTRjn8xBqp75dk7kFupVRt)。

    已核:+22 行纯新增(两条别名路由镜像有-app 分支 + catch-all),导航 URL 零改动;CI 18 检查 16 成功 2 跳过 0 失败;逆向验证 5 红且失败现场 DOM dump 零业务节点 — 白屏的字面证据。

    裁决记录:

    1. 规范拼法结论与派发预设相反,采纳 dev 的证据链(:751 注释 + LegacyMetadataRedirect 即 302 非页面 + docblock 明说翻译方向)— 修法不变但认知修正,console(apps/console): MetadataRedirect / ObjectRedirect 改写到已废弃的 component/metadata/resource 别名,多绕一跳且 docblock 已过期 #3639 已记录这个错误认知的来源(宿主仍往废弃别名改写)。
    2. 验收 URL 纠偏接受:/apps/setup/no-such-page 三个开关全不亮、进不了分支(:568 守卫先命中空态)— dev 换成真正进分支的两条 URL 并把原 URL 钉成 MEASUREMENT 边界,比派单的口径更准。
    3. 跨 vitest project 无法 import 宿主 MetadataRedirect 时逐字转写正则并注明出处 — 可接受的隔离处置。
    4. 新发现定级:console: isSystemRoute / isMetadataRoute 的子串判断把 /apps/未知app/system_log 认成伪路由,静默回退渲染另一个 app #3638 入队(bug) — 子串判断绕过 requestedAppMissing 守卫静默渲染另一个 app,正是 :193 注释要防的事;⚠️ 同文件串行等 3636 落 main。console(apps/console): MetadataRedirect / ObjectRedirect 改写到已废弃的 component/metadata/resource 别名,多绕一跳且 docblock 已过期 #3639 观察类入池(双跳重定向 + metadata:resource 注册表组件被打分遮蔽成休眠 — 修时别只删产出留遮蔽)。

    零应用 console 簇四单(#3590/#3609/#3610/#3611)全部交付。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions