Skip to content

bug(plugin-grid): ObjectGrid's relational copy set is a strict subset of what its own lookup cell and inline picker read (displayField, reference_field, descriptionField, lookup_columns never arrive) #6875

Description

@claude

Provenance: measured while implementing objectui#6711 (retiring the dead
reference_to_field from the same list). Filed unassigned. Not folded into that card — it
names one key and removes it; this is the opposite direction (keys with readers that are
never copied) and is a behaviour change, not a retirement.

What's measured

ObjectGrid's applyRelationalMeta copies a fixed list off the object-schema field def onto
each relational column's fieldMeta (packages/plugin-grid/src/ObjectGrid.tsx,
RELATIONAL_META_KEYS), and that bag is what the cell renderer and the inline picker
receive. The list is a strict SUBSET of what those two consumers read off the same bag.

Consumer reads, verbatim from packages/fields:

  • src/index.tsx (LookupCellRenderer):
    display_field || displayField || reference_field
  • src/widgets/LookupField.tsx:252 (the grid's inline picker):
    fieldMeta?.display_field || fieldMeta?.displayField || fieldMeta?.reference_field || 'name'
  • src/widgets/LookupField.tsx:253:
    fieldMeta?.description_field ?? fieldMeta?.descriptionField
  • src/widgets/LookupField.tsx:268:
    fieldMeta?.lookup_columns ?? fieldMeta?.lookupColumns
  • src/widgets/UserField.tsx:49:
    meta?.display_field || meta?.displayField || meta?.reference_field

Copied by the grid: display_field, description_field, lookup_filters, lookupFilters,
id_field, reference_to, reference (+ titleFormat, see objectui#6874).

Never copied, though read on the grid's own path:displayField, reference_field,
descriptionField, lookup_columns, lookupColumns.

Why this is not "the renderer just accepts extra spellings"

Two things make the omission specific rather than cosmetic:

  1. reference_field is a DECLARED objectui type member with readers all over the repo
    packages/types/src/field-types.ts (LookupFieldMetadata.reference_field),
    packages/types/src/views.ts, its zod mirror, and read by plugin-detail
    (RelatedList, RecordMetaFooter, RecordDetailDrawer, fieldEnrichment),
    plugin-charts (ObjectChart), plugin-form (deriveMasterDetail), plugin-list
    (ListView, UserFilters) and app-shell (resolveActionParams). Every one of those
    surfaces honours an author's reference_field; a lookup rendered by ObjectGrid does
    not, because the key never reaches the cell.

  2. The camelCase spellings are the SPEC-declared ones.@objectstack/spec@17.2.0's
    FieldSchema (64 props) declares displayField, descriptionField, lookupColumns,
    lookupFilters, reference — and none of display_field, description_field,
    lookup_filters, reference_to. The grid's list is mostly the objectql runtime
    spellings. It is internally inconsistent about this: lookupFilters (camel) IS in the
    copy set next to lookup_filters, while displayField and descriptionField are not
    next to their snake twins — so the list was assembled from a defect report rather than
    derived from the readers.

What is NOT measured here

  • Whether the object schema a live getObjectSchema returns ever carries the camelCase
    spellings (the server may normalise on the way out). That check decides how much of item 2
    is reachable today, and it is the first thing triage should run.
  • No user report is attached. This is a static producer-vs-consumer measurement.
  • packages/plugin-dashboard's CELL_RELATIONAL_META_KEYS has the same gap for
    displayField / reference_field: its docblock enumerates what LookupCellRenderer
    reads as three keys, and that enumeration missed the two extra spellings in the same
    fallback chain.

Shape of a fix

Contract-first says the answer may be at the producer (one spelling, normalised once) rather
than widening a hand-kept alias list in the renderer — AGENTS.md #0.1 is explicit that a
tolerant renderer fossilises a second dialect. Whatever the direction, the copy set should
be DERIVED from the consumers' read set rather than restated, so the two cannot drift again;
that is the same repair objectui#6711 and objectui#6874 approach from the dead-key side.

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions