Skip to content

record:line_items also issues find(undefined, …) for a panel whose childObject is unset — the sibling of #6188 in the same component #6194

Description

@yinlianghui-tw

Found while implementing #6188 and deliberately left unfixed there: that card's dispatch order scoped the fix to the getObjectSchema call in LineItemsPanel and said to file any further unguarded sub-key site rather than fix it.

Fact (objectui origin/main @ b04646b, measured)

LineItemsPanel reads schema.childObject at two sites. #6188 guards the first (the child-schema cache). The second — the row load — is still unguarded:

packages/plugin-form/src/LineItemsPanel.tsx:133-137

const load = useCallback(async () => {
if (!dataSource || !parentId) {
setLoading(false);
return;
}
…
const res = await dataSource.find(schema.childObject, { … });

The guard covers the data source and the parent id — the two things RelatedList calls "can I scope this query" — but not the object being queried. A panel authored without childObject therefore asks the backend to find an object literally named undefined, scoped by { [relationshipField]: parentId }.

Measured, mounting record:line_items through the registry with childObject unset and parentId: 'inv-1' authored. The recorded call list, by first argument:

before #6188: ['getObjectSchema(undefined)', 'find(undefined)']
after #6188: ['find(undefined)']

That second line is pinned as current behaviour in packages/plugin-form/src/LineItemsPanel.childObjectDecline.test.tsx with a comment pointing here — when this card lands, the expectation becomes toEqual([]) and the annotation goes.

Why it was not folded into #6188

Two reasons, and the second is why this deserves its own reading rather than a one-line rider:

  1. [finding] record:line_items issues getObjectSchema(undefined) for a panel whose childObject is unset, instead of declining to fetch #6188's dispatch order scoped it to the getObjectSchema call and named further sites file-not-fix.
  2. The decline is not purely mechanical here, unlike [finding] record:line_items issues getObjectSchema(undefined) for a panel whose childObject is unset, instead of declining to fetch #6188's. Declining a schema fetch has no visible consequence: the panel already holds null before any fetch resolves and the .catch already produced null. Declining the row fetch has one — load owns loading, and the panel's render branches loading ? "Loading…" : !parentId ? "Save the record first…" : <grid>. An unresolvable panel with a parent id bound would land on the third branch and show an empty editable grid with an Add button, over an object that does not exist. Whether that is right, or whether this case wants its own config-hint branch (the way MasterDetailForm's grid card shows one, [finding] object-master-detail-form issues getObjectSchema(undefined) for a detail collection whose object it never resolved, instead of declining to fetch #5940), is a question this card has to answer rather than assume.

Not verified here

  • Whether the same shape exists on the save path (buildMasterDetailEditBatch is handed childObject: schema.childObject unconditionally at LineItemsPanel.tsx:205). The Save button is disabled until the grid is dirty, so reaching it requires editing rows of the nonexistent object first — plausible but not measured.

Class

Same family as #6188 (whose reachability measurement is recorded there), #5940 / #6191 (object-master-detail-form, landed), #3838 and #3840 — an unresolved optional sub-key reaching a read unguarded. This is the fourth instance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:blocked

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions