Skip to content

bug(fields): a type: 'location' value spelled { lat, lng } reads as 0, 0 in LocationField while the same value renders correctly through LocationCellRenderer #6272

Description

@yinlianghui

Blocked-by: #6154

Filed unassigned while measuring #6154. Not fixed there — #6154 is a declaration card and bounced to the decision box; this is the runtime half it uncovered, and it is a separate defect.

Baseline: objectui main @ ef2a3bd8d.

The two consumers of one field type disagree

location has two consumers inside @object-ui/fields alone:

  • editLocationField (packages/fields/src/widgets/LocationField.tsx:14), which reads value.latitude / value.longitude and nothing else, each behind || 0.
  • displayLocationCellRenderer (packages/fields/src/index.tsx:2290), registered for locationandgeolocation at packages/fields/src/index.tsx:2428-2429, which accepts { lat, lng } / { lat, lon } / { latitude, longitude }, a "lat,lng" string, and a [lat, lng] array.

Measured by rendering both against the same values (vitest run from the repo root, happy-dom, throwaway probe, not committed):

stored valueLocationField (edit, readonly branch)LocationCellRenderer (display)
{ latitude: 30.2741, longitude: 120.1551 }30.2741, 120.155130.2741, 120.1551
{ lat: 30.2741, lng: 120.1551 }0, 030.2741, 120.1551
{ lat: 30.2741, lon: 120.1551 }0, 030.2741, 120.1551
"30.2741,120.1551"empty30.2741, 120.1551
[30.2741, 120.1551]0, 030.2741, 120.1551
nullemptyempty
{ latitude: 30.2741 }30.2741, 0raw JSON fallback

Why 0, 0 is the bad failure mode

0, 0 is not an error state — it is a valid coordinate in the Gulf of Guinea. A record whose location is stored in any spelling but { latitude, longitude } therefore renders as a plausible wrong place in the edit surface and as the right place in the detail/list surface, on the same record. The partial case is worse in the same direction: { latitude } alone reads 30.2741, 0, silently inventing a longitude the record does not carry.

This is not a hypothetical spelling

The repo itself stores type: 'location' values in both spellings:

  • { lat, lng }packages/plugin-detail/src/__tests__/DetailSection.addressDisplay.test.tsx:56 (field declared office_location: { type: 'location' } at :36), and packages/fields/src/__tests__/AddressCellRenderer.test.tsx:65,153, where a live assertion pins that a type: 'location' value spelled { lat, lng } renders containing 30.2741.
  • { latitude, longitude }examples/schema-catalog/src/schemas/fields-location/{san-francisco-coordinates,read-only-location}.json, packages/plugin-detail/src/__tests__/InlineFieldInput.composite.test.tsx.

packages/plugin-map/src/ObjectMap.tsx:435-459 reads record[locationField] with the same five-spelling tolerance as the cell renderer, so the map agrees with the display side and disagrees with the edit side too.

What is not ambiguous

The produce side is settled and single-shaped — measured from onChange:

onChange emissions = [{"latitude":30.2741,"longitude":120.1551}, null]

LocationField emits exactly { latitude: number; longitude: number } or null, never an alias spelling.

Repro

import{LocationField,getCellRenderer,resolveCellRendererType}from'@object-ui/fields';constv={lat: 30.2741,lng: 120.1551};// edit surface → "0, 0"{}}readonly/>// display surface → "30.2741, 120.1551"constR=getCellRenderer(resolveCellRendererType({type: 'location'}));

Not decided here

Which side moves is the same question #6154 is bounced on, and should be settled with it rather than separately: either the alias spellings are real (and the edit widget must read them, and the type published for #6154 must cover them), or they are not (and the display renderer's tolerance is the thing to retire, per AGENTS.md #0.1 — which would also require re-fixturing the two { lat, lng } test files above). Fixing only the edit widget would widen the tolerance the maintainer may want narrowed; fixing only the renderer would break a pinned assertion. Recording, not choosing.

Refs: #6154 (the declaration card this was measured under).


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain: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