Skip to content

finding(docs): docs/ARCHITECTURE.md's Next.js example has no 'use client' — app/layout.tsx and app/[object]/page.tsx are App Router server components as written and fail at runtime for a reader who copies them #8161

Description

@baozhoutao

Filed by the domain:devx @ objectui execution seat (PM session session_01FhBNJcLRZLe8M87VcUgpKr, R46, 2026-09-06T21:37Z) from the census objectui#7856 card 1 took while bringing docs/*.md into the doc-snippet walk (PR #8158, head f011733bf). A proposal that PR deliberately did NOT act on: the type-checker cannot see it, and the fix is a teaching decision (which file gets the directive, and whether the page should say why).

What the page says

docs/ARCHITECTURE.md, "Example 2: Next.js Integration" (two tsx fences after PR #8158's split, app/layout.tsx and app/[object]/page.tsx): the layout renders ThemeProvider / AppShell, the page calls the useDataSource() hook and renders ObjectView.

What the tree says (f011733bf)

  • The string 'use client' appears nowhere on the page (git grep -n "use client" origin/main -- docs/ARCHITECTURE.md is empty; control: the same grep over packages/app-shell/src is non-empty).
  • Under the Next.js App Router every file under app/ is a server component unless it carries the directive; a hook call (useDataSource) in a server component and a context provider rendered from one both fail at runtime. A reader copying the two fences literally gets that error.

Why it is a finding and not a repair rider

The doc-snippet gate compiles each fence as an isolated TSX module; a missing 'use client' produces no diagnostic, so no gate can hold this line. The fix is one directive line per fence plus, ideally, one sentence saying why, and belongs to whoever owns the page's teaching (it documents @object-ui/app-shell + @object-ui/providers integration). Pair with objectui#8160, filed from the same census on the same page.

Refs objectui#7856, PR #8158.

Activity

  1. added
    bugSomething isn't working
    documentationImprovements or additions to documentation
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    and removed on Sep 7, 2026
  2. added theissue type on Sep 7, 2026
  3. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    分诊 · 准入通过 (a) 类

    标签:domain:devx · documentation · bug · pm:queue · priority:p3 · type Bug
    finding 已摘。写前状态复核:open · 无 assignee · 无 PR。✅

    为什么是 (a) 而不是"文档 nit"——判据我说清楚

    (a) 的原文是「可复现缺陷(复现或失败探针具名)」。⇒ "复现"是被明确接受的两种证据之一,而本卡给了一个:把两段 fence 原样贴进一个 Next.js 应用 ⇒ 运行时报错。

    ⛔ (a) 里没有任何字把它限定在 packages/*/src。 docs/ARCHITECTURE.md 是本项目发布出去的产物,而它教的代码照做就坏。

    ⭐ 卡片的读数也带控制:git grep "use client" -- docs/ARCHITECTURE.md 为空,对照组(同一条 grep 打 packages/app-shell/src)非空 ⇒ 那个零是读数,⛔ 不是仪器没开。

    ⚠️ 与本轮/上轮几张文档卡的分界,请一并记住

    卡 文档的毛病 判定
    本卡 教的代码照做就报错 ✅ (a),立卡
    #7724(已关) 只列了 11 个属性里的 6 个 ⛔ 三类外 —— 不完整,⛔ 不是错
    #7984(已关) 只写了 4 个成员里的 2 个 ⛔ 同上

    ⇒ 分界是"不完整"与"错",⛔ 不是"文档 vs 代码"。

    p3 的理由(我考虑过 p2)

    失败是响亮且自解释的 —— Next.js 对"服务端组件里调 hook"给出的报错信息非常有名,任何 Next.js 开发者三十秒内解决。

    ⇒ 对比本轮的 #8279(设计器产出空白行 + 破折号、没有任何诊断)判 p2 —— 那里作者不知道自己错在哪。⇒ "坏得响亮"与"坏得安静"不该同档,这是我在本轮维持的一条分界。

    ⛔ 不抬 p2;⛔ 也不降 p4:这是集成路径的旗舰示例,照做必坏。

    交付物

    • ✅ 每段 fence 加一行 'use client',外加一句说明为什么 —— 卡片说得对,读者需要知道的是"App Router 下 app/ 里的文件默认是服务端组件",⛔ 不只是"抄这一行"。
    • ⚠️ 哪个文件拿这个指令是个教学取舍(layout 拿?page 拿?两个都拿?)—— ⛔ 我不替实施者定,但这不构成决策卡:三种写法都能工作,选哪个是作者偏好。
    • ⛔ 不要指望门禁:doc-snippet gate 把每段 fence 当独立 TSX 模块编译,缺 'use client' 不产生任何诊断。⇒ 这一条永远只能靠人读。

    配对

    与 #8160(同一页、同一次普查、DataSource 接口无人导出)成对。⭐ 建议同一个 PR 一起改 —— 同一页、同一个受众,分两次改是浪费一次评审。


    Triage: lands in docs/ARCHITECTURE.md ("Example 2: Next.js Integration"); rationale: class (a) — a named repro (copy the two fences into a Next.js App Router app) produces a runtime failure, since every file under app/ is a server component without the directive and the page calls useDataSource(). Graded p3 rather than p2 because the failure is loud and self-explaining, unlike objectui#8279's silent blank output. Pair with objectui#8160 in one PR.


    Generated by Claude Code

  4. claude commented on Sep 7, 2026

    @claude
    Contributor

    Claim: PM loop round R46 — domain:devx @ objectui execution seat.
    Session: session_01FhBNJcLRZLe8M87VcUgpKr
    Branch: claude/issue-8160-architecture-md-datasource-and-use-client
    Worktree: /home/user/objectui-issue-8160
    Domain: domain:devx
    File surface: docs/ARCHITECTURE.md only — SAME branch, worktree and PR as #8160.
    Dispatch: one os-dev subagent of this session (mode:subagent, model: opus); the dispatch note with the brief follows on this card. Labels pm:queue → pm:dispatched and assignee set in one write, read back at 2026-09-07T14:16Z.\n\nFold-or-serial, answered before either card was claimed (both want docs/ARCHITECTURE.md): ONE dev, ONE worktree, ONE PR carrying both — which is what triage recommended on each card ("同一页、同一受众,建议一个 PR 一起改,⛔ 别分两次评审"). ⛔ This is NOT a family fold: the defect forms differ (one is which interface the page should teach, the other is a missing App Router directive), so gate ① of the folding rule does not pass and neither card inherits the other's acceptance. What it IS: the same-file serial collapsed into a single dispatch, so the two never race the page. Each defect keeps its OWN named acceptance criterion and the PR body must show both, separately. ⛔ Excluded from this dispatch and named so: the any root cause under #7912 and #7483 (this is the documentation face of that seam, not its repair), and any other defect on the page that neither card measured.


    Generated by Claude Code

  5. claude commented on Sep 7, 2026

    @claude
    Contributor

    Dispatched together with #8160 — one dev, one worktree, one PR, per triage's recommendation on both cards. The full dispatch note is on #8160 (5571966268 region); the branch is claude/issue-8160-architecture-md-datasource-and-use-client and the claim on this card is 5571942832.

    This is not a family fold — the defect forms differ, so this card keeps its OWN acceptance criterion (the directive present in the affected fence(s) with the sentence explaining why App Router files are server components by default, and the zero-reading re-derived with a LIVE control) and the PR body shows it separately from #8160's. The PR carries Fixes #8161 on its own line.

    ⚠️ This card's control is dead and the dev was told so: use client occurs ZERO times in packages/app-shell/src on today's main, so the control this card offered for its zero-reading no longer fires. A live control exists in apps/site/app/** (75 files repo-wide carry the directive). The finding itself stands — the page has no directive — but it needs a control that fires to be a reading. — domain:devx @ objectui seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr, 2026-09-07T14:20Z.


    Generated by Claude Code

  6. claude commented on Sep 7, 2026

    @claude
    Contributor

    Handled together with #8160 in one PR (same page, same audience, per triage) — the two cards keep separate acceptance criteria and separate evidence.

    This card in one line: the zero on docs/ARCHITECTURE.md is real (exit=1, 0 lines) but this card'''s stated control was dead — packages/app-shell/src returns the same reading as the subject, because the packages ship no use client banner at all (built output: app-shell 0, providers 0, plugin-view 0, react 0). Re-derived against a live control that fires: apps/site/app, exit=0, 8 files; 75 repo-wide. Repair: the directive on both Example 2 fences plus a sentence explaining that every module under app/ is a server component by default. Note the directive is not gate-checkable — each fence compiles as an isolated module, so no gate validates an RSC boundary.


    Generated by Claude Code

  7. claude commented on Sep 7, 2026

    @claude
    Contributor

    LANDED: PR #8358 merged at 2026-09-07T14:57:31Z as 04597f3a5; 'use client' is on origin/main in both Example 2 fences, with a prose paragraph above the pair teaching the rule rather than the line.

    Both fences carry it, each for an independent reason — the page fence calls the useDataSource() hook, the layout fence renders context providers — and the directive is per-module, not inherited, so marking only one would have left the other broken. Example 3 deliberately does not get it: it declares no app/ path.

    This card's control was dead and is replaced. use client occurs ZERO times in packages/app-shell/src, so the control this card offered could never distinguish a working grep from a broken one. The cause turned out to be worth its own card: no @object-ui/* package ships the banner in source OR in built dist, filed as #8362. The zero on this page was re-derived against a control that fires (apps/site/app, 8 files; 75 repo-wide), and the finding stands.

    Stated in the PR rather than implied: 'use client' is uncheckable by any gate — each fence compiles as an isolated module, so no diagnostic can hold this line. It is a human-read invariant, and the page now teaches why rather than just carrying the directive.

    Closed via Fixes; pm:dispatched stripped in the same stroke. — domain:devx @ objectui seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr, 14:59Z.


    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

bugSomething isn't workingdocumentationImprovements or additions to documentationdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopriority:p3

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions