Skip to content

getRecordDisplayName step 0 reads objectDef.titleField — a key @objectstack/spec's object schema does not declare — and ranks it ABOVE the canonical nameField #6531

Description

@os-support-ai

Filed unassigned by the dev seat working objectui#6343 (session session_011SfZeFWrhGLHmfq61xbz4q), measured while establishing what the derived options.titleField at the interface-page map seam actually outranks. ⛔ Not touched by that PR: packages/core/src/utils/record-title.ts was explicitly fenced out of its file face, and a precedence change there is a decision, not a mechanical repair. Duplicate scan run before filing: 247 open objectui issues enumerated via the REST list endpoint and grepped for titleField / record-title / nameField / display name; no hits on this subject (positive control: the grep fires on #4716 and the enumeration contains #6343 itself).

What the code does

packages/core/src/utils/record-title.ts, step 0:

constexplicit=valueAt(record,options?.titleField)??valueAt(record,objectDef?.titleField);if(explicit)returnexplicit;

So an object-level titleField is consulted before step 1's objectDef.nameField, which ADR-0079 Phase 2 made the canonical record-title pointer, and before the deprecated displayNameField alias at step 2.

What the spec declares

@objectstack/spec's object schema (packages/spec/src/data/object.zod.ts:2040-2050) declares exactly three record-title keys on an object:

  • nameField — "[ADR-0079] Canonical primary title field";
  • displayNameField — "[DEPRECATED → nameField] … Accepted as an alias";
  • titleFormat — "[DEPRECATED → nameField (ADR-0079)] Render-only title template".

There is no object-level titleField. Measured across both repos' metadata: every titleField in objectstack/examples is view-level (gallery / calendar / timeline / gantt / map config, all of which the spec does declare — view.zod.ts:785, 799, 1124, 1166, 1267); zero object-level occurrences. Positive control for that zero: nameField fires in the same search space (examples/app-todo/src/objects/task.object.ts:209), and locationField fires in examples/app-showcase.

Why this is a card and not a cleanup

Two readings, and they lead to opposite edits — which is why nobody should pick one in passing:

  1. The leg is dead. Nothing spec-compliant can carry objectDef.titleField, so the read is a lenient consumer-side alias for a key no producer declares — the exact shape AGENTS.md Commandment #0.1 bans, and a live invitation for AI-authored metadata to spell the pointer three ways. Removing it makes the declared nameField the top of the ladder, as ADR-0079 says it is.
  2. The leg is load-bearing for loosely-typed metadata.getRecordDisplayName is deliberately defensive (objectDef is any; steps 4b/5 exist for partial shapes), and lookup chips / search candidates are documented as arriving with "only name/titleField" (see the NAME_ISH_RECORD_KEYS docblock in the same file). If some fetched shape really does carry titleField, deleting the read silently degrades those titles.

Reading 2 needs a census that this card does not have: which producers, if any, put titleField on an object-shaped payload. That census is the work here, and its answer decides between "remove the read" and "declare the key in the spec".

Either way the ORDER is separately questionable: even if the read stays, an undeclared/legacy key ranking above the canonical declared pointer inverts the same governed-authority default objectui#6343 restored one seam up.

Refs: objectui#6343 (where this was measured, and the seam that fed step 0 a derived name) · ADR-0079 · packages/spec/src/data/object.zod.ts:2040-2050 (objectstack).

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions