Context
Leaf of #18762, from the Fable evaluation round its Unresolved Liveness names. Measured on examples/grid/cellEditing at dev@3f859a4803, whose Country column edits through CountryField with bind: {store: 'stores.countries'} — the app-level store its countryRenderer also reads.
unowned-rationale: found while evaluating the epic; my lane is the example's e2e witness (#18837). Claimable by any seat.
The Problem
Observed
- Double-click a
Country cell whose record holds a code → the editor opens with an empty input.
- After one combo edit commits (ArrowDown, Enter on an item), Country cells render
'' on the next repaint.
Inferred from source, not measured beyond the symptoms
- While a bound store is pending,
beforeSetStore returns null (src/form/field/ComboBox.mjs:285–287), so beforeSetValue finds no store and returns the raw code under the comment "We will (re)set the value once the store is created" (:354–356). Nothing does: afterSetStore (:202–226) never re-resolves the value, and onStoreLoad (:679) runs only on a load event — which a shared store that loaded before the editor existed never fires for it.
afterSetStore pushes the field's typing filter onto the store it was handed (:207–217). Here that is the shared countries store: one editor per edit session adds one filter, none is removed when the editor is destroyed, and countryRenderer (examples/grid/cellEditing/MainContainer.mjs:33–41) resolves names against the filtered store. Falsifier: read that store's filters.length and getCount() before the first edit and after three sessions.
Corrected 2026-09-18 by @neo-opus-ada's intake (measured): inference 2 named the smaller half. The blank cells and the intermittent Cannot read properties of null (reading 'name') come from the field's teardown DESTROYING the shared store — its picker list defaults autoDestroyStore: true — and the filter's mid-session effect is real too (typing "Ger" leaves getCount() 1 for every other reader). PR #18857 carries both, with a field-owned view instead of filter removal.
The Architectural Reality
A ComboBox that creates its store owns it, and filtering it is private. A bound or passed store instance is not the field's: every other reader sees the filter. The grid editor makes it acute — editors are created and destroyed per session — but a form field bound to a provider store has the same two defects.
The Fix
In src/form/field/ComboBox.mjs: when a store arrives already loaded and the value is still a raw valueField/displayField value, resolve it to the record then; and keep the typing filter off a store the field does not own — filter a private view, or remove the field's own filter on destroy and picker hide. The owner picks after measuring.
Acceptance Criteria
Out of Scope
The picker trigger's pointer path (filed beside this leaf) · value: value?.[me.displayField] || null at :214 reading a field off the store — noted, not measured.
Avoided Traps
- Giving the example's editor a private copy of the countries store: repairs the example and leaves both field defects for every consumer.
Related
Parent #18762 · #18771 (the renderer this column uses) · #18764.
Live latest-open sweep: latest 20 open issues at 2026-09-18T10:27Z plus an open-issue search for ComboBox store filter — no equivalent (#7224 is a Store guide). A2A sweep (latest 12, all read-states): no claim on this scope. Memory sweep: one hit, my own measurement checkpoint.
Origin Session ID: 323cb989-06a2-4b3f-8d70-912d67796c11
Retrieval Hint: "ComboBox bind store raw value never re-resolved; typing filter left on shared store; grid country editor empty"
Context
Leaf of #18762, from the Fable evaluation round its Unresolved Liveness names. Measured on
examples/grid/cellEditingatdev@3f859a4803, whose Country column edits throughCountryFieldwithbind: {store: 'stores.countries'}— the app-level store itscountryRendereralso reads.unowned-rationale: found while evaluating the epic; my lane is the example's e2e witness (#18837). Claimable by any seat.
The Problem
Observed
Countrycell whose record holds a code → the editor opens with an empty input.''on the next repaint.Inferred from source, not measured beyond the symptoms
beforeSetStorereturnsnull(src/form/field/ComboBox.mjs:285–287), sobeforeSetValuefinds no store and returns the raw code under the comment "We will (re)set the value once the store is created" (:354–356). Nothing does:afterSetStore(:202–226) never re-resolves the value, andonStoreLoad(:679) runs only on aloadevent — which a shared store that loaded before the editor existed never fires for it.afterSetStorepushes the field's typing filter onto the store it was handed (:207–217). Here that is the sharedcountriesstore: one editor per edit session adds one filter, none is removed when the editor is destroyed, andcountryRenderer(examples/grid/cellEditing/MainContainer.mjs:33–41) resolves names against the filtered store. Falsifier: read that store'sfilters.lengthandgetCount()before the first edit and after three sessions.Corrected 2026-09-18 by @neo-opus-ada's intake (measured): inference 2 named the smaller half. The blank cells and the intermittent
Cannot read properties of null (reading 'name')come from the field's teardown DESTROYING the shared store — its picker list defaultsautoDestroyStore: true— and the filter's mid-session effect is real too (typing "Ger" leavesgetCount()1 for every other reader). PR #18857 carries both, with a field-owned view instead of filter removal.The Architectural Reality
A ComboBox that creates its store owns it, and filtering it is private. A bound or passed store instance is not the field's: every other reader sees the filter. The grid editor makes it acute — editors are created and destroyed per session — but a form field bound to a provider store has the same two defects.
The Fix
In
src/form/field/ComboBox.mjs: when a store arrives already loaded and the value is still a rawvalueField/displayFieldvalue, resolve it to the record then; and keep the typing filter off a store the field does not own — filter a private view, or remove the field's own filter on destroy and picker hide. The owner picks after measuring.Acceptance Criteria
bind.storeto an already-loaded store and a rawvalueshows the matching record's display text once the store arrives.filtersandgetCount()equal what they were before the field existed.devfirst.Out of Scope
The picker trigger's pointer path (filed beside this leaf) ·
value: value?.[me.displayField] || nullat:214reading a field off the store — noted, not measured.Avoided Traps
Related
Parent #18762 · #18771 (the renderer this column uses) · #18764.
Live latest-open sweep: latest 20 open issues at 2026-09-18T10:27Z plus an open-issue search for
ComboBox store filter— no equivalent (#7224 is a Store guide). A2A sweep (latest 12, all read-states): no claim on this scope. Memory sweep: one hit, my own measurement checkpoint.Origin Session ID: 323cb989-06a2-4b3f-8d70-912d67796c11
Retrieval Hint: "ComboBox bind store raw value never re-resolved; typing filter left on shared store; grid country editor empty"