Skip to content

objectui: the two selectFirst gate hints join controlling-field names with hardcoded separators — and with two DIFFERENT ones #5432

Closed as not planned

Description

@yinlianghui

Observation-class finding, noticed while fixing objectstack#5407. Nothing a user hits today with any urgency — it needs a field gated on two or more controlling fields, which is rare — so it carries finding and no pm:queue. Recording it because #5407 has just established the mechanism that fixes it.

#5407 item 4 established that a list separator is a locale property, and added validation.formInvalidJoiner (per-pack: ", " for Latin scripts and Korean, "、" for zh/ja, U+060C + space for Arabic) after measuring Intl.ListFormat and finding its output unusable for a truncated list.

Two other sites join user-visible names with a hardcoded separator, and they do not even agree with each other:

Site Separator Sentence
packages/fields/src/widgets/LookupField.tsx ", " lookup.selectFirst
packages/components/src/renderers/form/form.tsx (option-field gate) " / " fields.options.selectFirst

Both fill the {{fields}} slot of what is deliberately one shared sentence — the form renderer's own comment says the two callers exist so "the gate can never read differently depending on which side produced it" — yet a field gated on two parents reads Select Account, Owner first from the lookup and 请先选择Account / Owner from the select. Under zh/ja both separators are wrong for the script on top of that.

Suggested fix

Reuse the mechanism #5407 added rather than inventing a second one: either read validation.formInvalidJoiner at both sites, or (if the gate hint wants its own punctuation) add one fields.gateJoiner key across the ten packs. Either way it has to be one key read by both callers — two keys would recreate the divergence the shared sentence exists to prevent.

Note for the implementer: LookupField receives the labels through the dependsOnLabels prop #5407 added, so the joining happens in dependsOnFieldsText there; the form's copy is in the gatedHint memo.

Activity

  1. added
    repo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 5, 2026
  2. added
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 5, 2026
  3. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    Contributor

    发现分诊轮:晋级 pm:queue(摘 finding,保留 repo:objectui)。理由:具体缺陷、两处落点已点名(LookupField.tsx 的 dependsOnFieldsText 与 form.tsx 的 gatedHint memo),修复机制 #5407 已落地(validation.formInvalidJoiner),issue 已写死约束「必须一个 key 两处消费」—— 纯执行单,无待决项;触发面虽窄(多父门控字段)但共享句「两侧产出必须一致」的设计不变式当下已被违反。本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Migrated to objectstack-ai/objectui#4026 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.


    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

No one assigned

    Labels

    pm:queueReady for the PM dispatch looprepo:objectuiSeam card: cross-repo ordering with objectui is the substance (pure objectui fixes live in objectui)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions