Found while implementing #6360, which fixes the render half of the !d.childObject decline in MasterDetailForm. This is the same permanent-spinner defect reached by the other arm of the same resolver, and #6360's scope was explicitly the decline arm only.
Fact (read from source, origin/main @ f53a8d0ae)
MasterDetailForm's detail-resolution effect has two arms that return the detail entry unresolved. packages/plugin-form/src/MasterDetailForm.tsx:
if (!d.childObject) { // arm 1 — the #5940 decline. FIXED by #6360.
console.warn(...);
return d;
}
try {
...
} catch {
return d; // arm 2 — the schema fetch FAILED. Still unhandled.
}
Both arms return an entry with no columns. The render branch then reads:
{!d.childObject ? (
<p data-testid="md-detail-no-child-object">…set `childObject`…</p> // ← #6360's new arm
) : !d.columns?.length ? (
<p>Loading columns…</p> // ← arm 2 lands HERE
) : (
Arm 2's entry does name a child object, so it skips the new hint and falls to Loading columns…. The fetch that would have supplied those columns has already failed and is not retried, so that message is permanent — the exact defect #6360 was filed for, one arm over.
Note this is not a runtime measurement: it is a direct read of the two code paths. The reason it was not measured is the reason it is hard to fix — see below.
Why the source comment is being corrected rather than made true
:400 read return d; // leave as-is; the grid card will show a config hint. It was false when #6360 was filed and it stays false for this arm after #6360, so #6360 corrects the comment to say what actually happens and points here. That keeps the file honest but leaves the behaviour.
Why this needs a decision, not a mechanical fix
Telling "the fetch failed" apart from "the fetch is still in flight" needs per-entry error state the resolver does not keep — resolvedDetails is a plain MasterDetailDetailConfig[], and both states are represented identically (no columns). Options, none free:
- carry a resolution status per entry (changes the resolver's internal shape),
- render a distinct refusal placeholder for the caught error (
AdvancedChartImpl's refusal placeholders are the precedent),
- or retry/surface the error the way
LineItemsPanel surfaces error above its branch.
The catch is also currently bare — the thrown error is discarded, so even a console.warn naming the object (which arm 1 does have) is unavailable to whoever debugs this.
Class
Same family as #5940 / #6188 / #6194 / #6360 — the "unbounded wait shown as a spinner" half. #6194's dispatch order ruled the shape out by name for record:line_items: "do not let loading stay true forever as a way of hiding the state." This is the last arm in MasterDetailForm where it still does.
Filed unassigned for triage.
Generated by Claude Code
Found while implementing #6360, which fixes the render half of the
!d.childObjectdecline inMasterDetailForm. This is the same permanent-spinner defect reached by the other arm of the same resolver, and #6360's scope was explicitly the decline arm only.Fact (read from source,
origin/main@f53a8d0ae)MasterDetailForm's detail-resolution effect has two arms that return the detail entry unresolved.packages/plugin-form/src/MasterDetailForm.tsx:Both arms return an entry with no
columns. The render branch then reads:Arm 2's entry does name a child object, so it skips the new hint and falls to
Loading columns…. The fetch that would have supplied those columns has already failed and is not retried, so that message is permanent — the exact defect #6360 was filed for, one arm over.Note this is not a runtime measurement: it is a direct read of the two code paths. The reason it was not measured is the reason it is hard to fix — see below.
Why the source comment is being corrected rather than made true
:400readreturn d; // leave as-is; the grid card will show a config hint. It was false when #6360 was filed and it stays false for this arm after #6360, so #6360 corrects the comment to say what actually happens and points here. That keeps the file honest but leaves the behaviour.Why this needs a decision, not a mechanical fix
Telling "the fetch failed" apart from "the fetch is still in flight" needs per-entry error state the resolver does not keep —
resolvedDetailsis a plainMasterDetailDetailConfig[], and both states are represented identically (nocolumns). Options, none free:AdvancedChartImpl's refusal placeholders are the precedent),LineItemsPanelsurfaceserrorabove its branch.The
catchis also currently bare — the thrown error is discarded, so even aconsole.warnnaming the object (which arm 1 does have) is unavailable to whoever debugs this.Class
Same family as #5940 / #6188 / #6194 / #6360 — the "unbounded wait shown as a spinner" half. #6194's dispatch order ruled the shape out by name for
record:line_items: "do not letloadingstay true forever as a way of hiding the state." This is the last arm inMasterDetailFormwhere it still does.Filed unassigned for triage.
Generated by Claude Code