Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Record detail page renders address fields as raw JSON — the display registry has a location formatter but no address one #4037

Closed

Description

@os-zhuang

Migrated from objectstack-ai/objectstack#5019 under the file-at-destination ruling (objectstack-ai/objectstack#7167, maintainer 2026-08-10). Originally filed 2026-08-03T23:58:21Z. The full prior thread — including triage rulings and hold/restart conditions — remains on the source issue and MUST be read before acting on this card.


Summary

On a record detail page, a Field.address value renders as a stringified JSON object instead of a formatted address. The same field renders correctly in the create/edit dialog, so this is specific to the detail page's read renderer.

Observed on protocol ^17.0.0-rc.1 in a zh-CN console.

Evidence

The decisive comparison is same record, same page, same field group — one address field next to one location field:

field type detail page (read)
billing_address Field.address ❌ {"street":"中策路 1 号","city":"杭州",…}
office_location Field.location ✅ 📍 30.2741, 120.1551

So the detail page's display renderer has a location formatter and lacks an address one, falling through to stringifying the object.

Meanwhile the create/edit dialog renders the same billing_address correctly as Street / City / State / ZIP / Country inputs.

This matches the shipped console bundle: the input registry carries both address: and location:; the display registry the detail page uses does not carry address.

The detail page's inline edit mode also shows the JSON.

Scope

Type-level, not object-specific. Confirmed by writing a value into a second object's address field through the API (crm_quote.billing_address) and seeing the same JSON rendering; reverted afterwards.

Any app with a populated Field.address on a detail page is affected.

Why there is no reasonable app-side workaround

Downstream consumers of ours evaluated and rejected each of these:

  • Change the field to text — destroys the structured value and breaks derivations that read sub-fields (in our case a billing_address.country projection that territory sharing rules match on), and loses the sub-field inputs that currently work.
  • Add a mirrored display-only field — puts two addresses on the page that can drift apart.
  • Author detail-page sections — that changes where the value comes from, not the renderer that formats it.

Expected

The detail page's display registry resolves address the way it resolves location, rendering a formatted postal address.

Related

Same family as objectstack-ai/objectstack#4854 (view/report/dataset label translation path) in that it is a renderer-registry gap on one surface while a sibling surface handles it correctly, though the mechanism is different — this one is a missing formatter, not a missing i18n lookup.

Activity

  1. self-assigned this
    on Aug 10, 2026
  2. yinlianghui commented on Aug 10, 2026

    @yinlianghui
    Contributor

    CLAIM (objectui whole-repo seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3) — dispatching a dev agent now.

    • Branch claude/issue-4037-address-display-formatter, worktree objectui-issue-4037 (S container)
    • Scope per the card: the detail page's display registry resolves address the way it resolves location — a formatted postal address in read mode and inline-edit read state, not stringified JSON. The source thread objectstack#5019 (and the test(plugin-grid): render what the inline lookup picker actually receives #7167 migration ruling) will be read before any code, per the card's header.

    Generated by Claude Code

  3. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    Contributor

    ACCEPT (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4215, delivered across two host restarts (gen-1/2 implementation inherited UNVERIFIED and then verified first-hand, rebased, changeset added).

    The layout rule is lifted, not invented: Street, City, State ZIP, Country is what AddressField's readonly branch already applied, now moved into one React-free module both surfaces call — a readonly form and a detail page can no longer spell one address two ways, and the eager barrel formats a cell without pulling the widget's lazy chunk. Inline-edit READ state covered through the single displayValue seam and pinned through the real DetailSection. The source thread objectstack#5019 was read in full (no hold, no format ruling). Two reverse-verification deviations reported honestly and handled correctly: the completeness assertion is not counted as red-first evidence, and the broken location control (it restated the defect pins instead of controlling for them) was fixed in its own commit and re-proven in both directions. Consumer sweep failures investigated to the unbuilt-dependency trap, not assumed.

    Delegated ruling on the open question (veto window open): A — one uniform order, as shipped. Locale-aware ordering (B) would make the detail line disagree with the readonly form line and the top-to-bottom input order on the same page, inverting the exact inconsistency this card fixed, on the strength of one screenshot's locale with no format ruling anywhere upstream. The genuine long-term case for B (a zh address street-first reads wrong) is real but is ONE deliberate contract change — formatAddress + the input widget's field order together — which now has a single home to land in; a follow-up card if the maintainer wants it.

    Finding #4216 (inline-edit INPUT path collapses address to a [Object] text box and emits a string over the structured object — data-destroying, distinct from this display fix) is graded queue, bug — the seat is queuing it now. CI converged 20/20, real changeset (fields patch; plugin-detail test-only). Flipping ready + auto-merge.


    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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions