Skip to content

lint: translation-target-unknown misses a view container's DEFAULT form.sections — correctly translating a rendered heading is reported as a stale key #5415

Closed

Description

@baozhoutao

validate-translation-references derives an object's legal _sections names from three anchors (packages/lint/src/validate-translation-references.ts):

  • fieldGroups[].key (line 346-349),
  • named sections on listViews / formViews sub-views (line 234-255),
  • named record:details sections on pages (line 358-368),
  • plus the view's OWN sections (line 257-262).

collectViewRecord iterates for (const key of ['listViews', 'formViews']). The view CONTAINER's default form is not in that list, and it is not the view's own sections either — so view.form.sections[].name contributes nothing to the fact set, even though ObjectForm renders that form and translates its headings through the very same sectionLabel(object, section.name, ...) convention.

Repro against in-repo metadata

examples/app-showcase/src/ui/views/contact.view.ts declares the default form with four named sections (contact, work, status, notes) bound to showcase_contact. A bundle that correctly translates one of them:

translations: [{ 'zh-CN': { objects: { showcase_contact: { _sections: { contact: { label: '联系方式' } } } } } }]

validateTranslationReferences(stack) returns:

rule:     translation-target-unknown
severity: warning
where:    locale "zh-CN" · object "showcase_contact" · section "contact"
message:  Translations are keyed to section "contact", which nothing on object
          "showcase_contact" declares — no `fieldGroups[].key`, no named form-view
          section, no named `record:details` section. The section heading stays in
          the source locale.
hint:     ... Object "showcase_contact" declares no named section at all.

Both the message and the hint are false: the object declares four named sections and the heading DOES resolve at render time. The advice the finding gives ("give the section a name and use it here, or drop the translation") points the author at deleting a translation that works.

Why it matters more now

PR for #5405 adds a section kind to the CLI i18n walker, and its second source is exactly this surface — the container default form, formViews.*, and page record:details. So after #5405, os i18n extract scaffolds objects.showcase_contact._sections.contact.label, and os lint immediately reports the key it just scaffolded as an unknown target. The two rules will contradict each other on real showcase metadata.

The #5405 walker deliberately covers view.form.sections because that is what the renderer reads; this issue is the reference validator catching up on the same anchor. The set relationship the two should hold is: every key the coverage walker DEMANDS must be a key the reference validator ACCEPTS.

Suggested fix

In collectViewRecord, feed the container's default form through the same section-name collection as formViews.* entries, binding it via bindingOf(view.form) ?? listBinding (mirroring how viewObjectName in the CLI walker resolves view.form.data.object). Worth a fixture pinning the showcase ContactViews shape so the anchor list cannot silently lose an entry again.

Found while implementing #5405 (out of scope there: packages/lint, and #5405 is CLI-walker scoped). Related: #5164 (the _views spelling disagreement — the same producer-drift family on the neighbouring key group).

Code references pinned to b4872a868.

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Aug 5, 2026
  2. self-assigned this
    on Aug 5, 2026
  3. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    ContributorAuthor

    分诊(cli 车道 PM,session_016FNvXhtSdnEGEfLEsMmvxh,2026-08-05):入队 pm:queue,domain:devx,即时借道派发。判级:auto-queue 类 —— 具名位置(collectViewRecord 只遍历 ['listViews','formViews'])+ 对仓内 showcase 元数据的实证复现(正确翻译真实渲染的标题被报 translation-target-unknown,hint 还是反向建议删掉能用的翻译)+ 修法明确。时效理由:PR #5416(#5405)已验收入队,落地后 extract 刮出的 key 会立刻被本缺陷判为未知目标 —— 两条规则在真实元数据上互相打架,窗口越短越好。应有不变量:覆盖走查器要求的每个 key 必须是引用校验器接受的 key。

    认领:PM 循环第 2 轮(cli 车道 PM 借道 devx)
    会话:session_016FNvXhtSdnEGEfLEsMmvxh
    分支:claude/issue-5415-lint-container-form-sections
    Worktree:objectstack-issue-5415
    域:domain:devx(借道:devx 域现无登记属主,单单借道不改登记表归属;文件面声明如下,全局在飞已核 —— 在队列中的 PR #5416 触 lint/src/index.ts,与本单不同文件)
    文件面:packages/lint/src/validate-translation-references.ts + packages/lint 对应测试

    执行口径:按 issue 建议修法 —— collectViewRecord 把容器默认 form 经与 formViews.* 相同的段落名收集路径,绑定取 bindingOf(view.form) ?? listBinding(与 CLI walker 的 viewObjectName 解析对齐);补 showcase ContactViews 形状的 fixture,钉住锚清单不再静默丢项。若可行,加「#5405 走查器要求的 key ⊆ 本校验器接受的 key」的集合关系断言(用真实 showcase 元数据)。


    Generated by Claude Code

  4. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    ContributorAuthor

    验收(cli 车道 PM 借道 devx,session_016FNvXhtSdnEGEfLEsMmvxh):ACCEPT → PR #5422。


    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 workingdomain:devxDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions