Skip to content

object-master-detail-form shows "Loading columns…" forever for a detail whose childObject never resolved — the promised config hint does not exist #6360

Description

@os-warren

Found while implementing #6194 (PR #6359), whose dispatch order named #5940's "config-hint precedent" as the default to follow. Reading that precedent to copy it is what turned this up. Not fixed there — out of scope for that card, which is confined to LineItemsPanel.

Fact (objectui origin/main @ ed859aa35, measured)

MasterDetailForm declines to fetch the schema of a detail collection whose childObject never resolved (#5940), and returns the detail entry as-is. Two comments state what the user is then supposed to see:

packages/plugin-form/src/MasterDetailForm.tsx:351-352

// Left as-is rather than dropped, exactly like the `catch` below — the
// grid card shows a config hint, and `details` stays length-matched to

packages/plugin-form/src/MasterDetailForm.tsx:382

return d; // leave as-is; the grid card will show a config hint

There is no config hint. The branch those comments point at is :242-243:

{!d.columns?.length ? (
  <p className="py-4 text-sm text-muted-foreground">Loading columns…</p>
) : (

For a declined detail the columns can never arrive — that is precisely what the decline guarantees — so "Loading columns…" is a spinner-shaped message that is permanently, unfixably wrong, and it never names the key the author has to set.

Measured, mounting object-master-detail-form through the registry with objectName: 'invoice' and details: [{ title: 'Probe Detail' }] (no childObject, no columns, so the derive path is entered and then declines):

rendered text  = "Probe DetailLoading columns…Create"
contains "childObject" = false
data calls     = ['getObjectSchema("invoice")']   // the parent's own; the detail's was declined

The single call confirms the decline fired and no second attempt is pending.

Why this is worth its own card

It is the same defect the #6194 dispatch order ruled out by name for record:line_items: "do not let loading stay true forever as a way of hiding the state." LineItemsPanel now takes the other branch — a hint naming childObject and what to set it to, checked ahead of loading because nothing is pending (PR #6359). The two components now disagree about what an author sees for the identical authoring mistake, and the one that reads as the precedent is the weaker of the two.

It also makes the two comments above false documentation: the next reader who follows them, as I did, is told a config hint exists and has to run the component to find out it does not.

Class

Same family as #5940 / #6188 / #6194 / #3838 / #3840 — an unresolved optional sub-key reaching a read unguarded. This is not another unguarded read (that half is fixed); it is the render half of #5940 left undone, and it is the fifth instance of the family by a different route.

Suggested shape (not a decision)

The branch already exists and is length-matched; it needs to distinguish "columns have not arrived yet" from "columns can never arrive". The discriminator is available at the call site — an entry with no childObject is the declined case. LineItemsPanel.tsx (after #6359) and AdvancedChartImpl's refusal placeholders are both prior art for the copy.

Filed unassigned for triage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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