You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
finding(plugin-dashboard): lookup cells in ObjectDataTable / RecordDetailDrawer never get reference_to/reference — refSchema-driven resolution and drill-through links never engage #6694
Provenance: found while implementing #6597 (the FieldMeta.referenceTo enforce-or-remove
card). Filed unassigned, no pm:queue label — this is an observation of a real gap in
existing behaviour, not a scoped fix; severity is for triage to set.
What's measured
plugin-dashboard's FieldMeta (packages/plugin-dashboard/src/recordFields.tsx) is the
object buildFieldMeta returns and ObjectDataTable / RecordDetailDrawer pass to renderFieldValue → getCellRenderer → <Renderer value={value} field={fieldMeta} />
(@object-ui/fields). For a lookup/master_detail field, that renderer is LookupCellRenderer (packages/fields/src/index.tsx), which resolves its reference
target from (field as { reference_to?: string }).reference_to || (field as { reference?: string }).reference — never any other spelling.
FieldMeta never carries either key. Grep confirms zero reference_to / .reference
writes anywhere in recordFields.tsx or ObjectDataTable.tsx — buildFieldMeta used to
resolve a referenceTo (camelCase) member (retired by #6597, itself measured dead end to
end), but neither before nor after that retirement did anything write the snake_case
spelling LookupCellRenderer actually reads.
Two consequences, both currently silent:
useRefObjectSchema(referenceTo) inside LookupCellRenderer always resolves undefined for cells rendered through this path, so the referenced object's schema
(nameField / titleFormat) never loads. Display-name resolution for these cells always
falls back to pickRecordDisplayName's generic .name/.title heuristic instead of
the schema-aware resolution issue [fields] Lookup chip 显示值走 autonumber 启发式,与 picker(nameField/titleFormat)解析不一致 #2357 built. This is silent because the generic
fallback usually still produces a readable name — it only diverges when the referenced
object's display field isn't literally name/title.
ReferencedRecordLink's objectName prop is always undefined for these cells, so navigable is always false and the cell never renders a real <a> — no drill-through
click, no middle-click-new-tab, no copy-link, for ANY lookup cell in ObjectDataTable
or the RecordDetailDrawer. This is silent because the cell still renders fine (as
plain text via the embedded { id, name } object's display name), so nothing looks
broken — it just never links.
Positive control confirming the read path itself is fine elsewhere: ObjectGrid
(packages/plugin-grid/src/ObjectGrid.tsx) DOES feed reference_to / reference onto its
own built fieldMeta via applyRelationalMeta, copied straight off the object schema
field def at all three of its call sites — so grid cells in that package get both the
schema-aware name resolution and working drill-through links. plugin-dashboard's two
widgets never adopted the equivalent copy.
Suggested fix shape (not prescriptive — untried)
ObjectDataTable.enrich() and RecordDetailDrawer's per-field loop both already have the
object schema field def in scope (fieldsByName[col.accessorKey] / def). Copying reference_to (and, for parity with ObjectGrid, display_field / id_field / description_field) from the schema field def onto the built fieldMeta — the same move applyRelationalMeta makes — would close both gaps. This is a NEW read (behaviour change,
not a retirement), so it needs its own measurement/authoring pass, which is why it isn't
folded into #6597 (that card's own stop-and-report line: enforcing must not widen
behaviour beyond the documented column-override promise, and this isn't that promise —
it's a different, unrelated gap the investigation surfaced).
Scope note
Not filed against #6597 as a sub-issue: it doesn't depend on that card's ruling either way
(the gap predates and survives both the enforce and withdraw branches — it was present
when referenceTo was still a FieldMeta member, since that member was never the
snake_case spelling either). Filed as an independent card in this repo, since the fix
lands in plugin-dashboard.
Provenance: found while implementing #6597 (the
FieldMeta.referenceToenforce-or-removecard). Filed unassigned, no
pm:queuelabel — this is an observation of a real gap inexisting behaviour, not a scoped fix; severity is for triage to set.
What's measured
plugin-dashboard'sFieldMeta(packages/plugin-dashboard/src/recordFields.tsx) is theobject
buildFieldMetareturns andObjectDataTable/RecordDetailDrawerpass torenderFieldValue→getCellRenderer→<Renderer value={value} field={fieldMeta} />(
@object-ui/fields). For a lookup/master_detail field, that renderer isLookupCellRenderer(packages/fields/src/index.tsx), which resolves its referencetarget from
(field as { reference_to?: string }).reference_to || (field as { reference?: string }).reference— never any other spelling.FieldMetanever carries either key. Grep confirms zeroreference_to/.referencewrites anywhere in
recordFields.tsxorObjectDataTable.tsx—buildFieldMetaused toresolve a
referenceTo(camelCase) member (retired by #6597, itself measured dead end toend), but neither before nor after that retirement did anything write the snake_case
spelling
LookupCellRendereractually reads.Two consequences, both currently silent:
useRefObjectSchema(referenceTo)insideLookupCellRendereralways resolvesundefinedfor cells rendered through this path, so the referenced object's schema(nameField / titleFormat) never loads. Display-name resolution for these cells always
falls back to
pickRecordDisplayName's generic.name/.titleheuristic instead ofthe schema-aware resolution issue [fields] Lookup chip 显示值走 autonumber 启发式,与 picker(nameField/titleFormat)解析不一致 #2357 built. This is silent because the generic
fallback usually still produces a readable name — it only diverges when the referenced
object's display field isn't literally
name/title.ReferencedRecordLink'sobjectNameprop is alwaysundefinedfor these cells, sonavigableis alwaysfalseand the cell never renders a real<a>— no drill-throughclick, no middle-click-new-tab, no copy-link, for ANY lookup cell in
ObjectDataTableor the
RecordDetailDrawer. This is silent because the cell still renders fine (asplain text via the embedded
{ id, name }object's display name), so nothing looksbroken — it just never links.
Positive control confirming the read path itself is fine elsewhere:
ObjectGrid(
packages/plugin-grid/src/ObjectGrid.tsx) DOES feedreference_to/referenceonto itsown built
fieldMetaviaapplyRelationalMeta, copied straight off the object schemafield def at all three of its call sites — so grid cells in that package get both the
schema-aware name resolution and working drill-through links.
plugin-dashboard's twowidgets never adopted the equivalent copy.
Suggested fix shape (not prescriptive — untried)
ObjectDataTable.enrich()andRecordDetailDrawer's per-field loop both already have theobject schema field def in scope (
fieldsByName[col.accessorKey]/def). Copyingreference_to(and, for parity withObjectGrid,display_field/id_field/description_field) from the schema field def onto the builtfieldMeta— the same moveapplyRelationalMetamakes — would close both gaps. This is a NEW read (behaviour change,not a retirement), so it needs its own measurement/authoring pass, which is why it isn't
folded into #6597 (that card's own stop-and-report line: enforcing must not widen
behaviour beyond the documented column-override promise, and this isn't that promise —
it's a different, unrelated gap the investigation surfaced).
Scope note
Not filed against #6597 as a sub-issue: it doesn't depend on that card's ruling either way
(the gap predates and survives both the enforce and withdraw branches — it was present
when
referenceTowas still aFieldMetamember, since that member was never thesnake_case spelling either). Filed as an independent card in this repo, since the fix
lands in
plugin-dashboard.