You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RealmResultsProxy.filtered passes wrapped entities through to Realm — throws under Realm 12 #70
RealmResultsProxy wraps objects on the way out (map/getAt → createEntity → new entityClass(realmObject)) but never unwraps them on the way back in: filtered() forwards its query args verbatim (src/framework/RealmResultsProxy.js:50-56):
So any client code that round-trips an entity — get it from a query, hand it back as a
link-equality argument — passes a plain wrapper instance (real object on .that) where
Realm expects a managed object. Realm 10/11 tolerated this; Realm 12's binding rejects it:
Error: Unable to convert an object with ctor 'SubjectType' to a Mixed
Field crash in avni-client's DB-restore path: avniproject/avni-client#2004
(getAllDirectlyAssignable().map(_.identity) → filtered('subjectType = $0', wrapper)).
Every other entry point already handles this
RealmProxy.create (src/framework/RealmProxy.js:61) and RealmProxy.delete (:100) both
unwrap via the existing helper:
Safe for primitives: getUnderlyingRealmObject requires .that / .realmCollection / .realmList (RealmCollectionHelper.js), so strings/numbers/dates return null and || arg passes them through untouched.
Context
avni-client#2004 worked around the three affected call sites by comparing link.uuid = $0 with primitive uuids — worth keeping regardless, as it's more robust.
But the gap stays open at the framework level: the next filtered('link = $0', entityWrapper) anyone writes throws the same Realm 12 error.
This closes it for all queries at once.
b0ba051 — query path, as proposed above. RealmResultsProxy.filtered unwraps its args, element-wise over arrays so IN $0 is covered too. Confirmed against realm 12.14.2 that it rejects both a wrapper and an array of wrappers — though no caller writes an IN query today, so that half closes the gap rather than fixing a live break.
c339a6d — write path (the extra bit). Reviewing the first fix turned up the same defect going the other way:
RealmListProxy.splice / unshift forwarded values to realmList verbatim, wrappers included.
RealmListProxy.push read x.that unconditionally, so anything that wasn't a wrapper was written to realm as undefined.
PersistedObject.fromEntityList (51 call sites) had the same x.that idiom, while its neighbour fromObject already guarded against it.
All four now route through one unwrapForRealm in RealmCollectionHelper. RealmProxy.create/delete keep their own variants for now — hot paths, and their divergences want a change of their own.
ArrayHelper.basePullAt is the live caller of splice and only ever deletes (no values), so it's unaffected — pinned by a test. No realm list holds primitives today, so the undefined write was a dead path. Suite 402 → 415.
Reaches avni-client only after a v1.33.77 publish; avni-client#2004's call-site workaround stays regardless.
Activity
#70 | Unwrap avni wrappers in RealmResultsProxy.filtered query args
#70 | Unwrap avni wrappers on the realm write path too
ombhardwajj commentedon Aug 20, 2026
Fixed on
17.2in two commits.b0ba051 — query path, as proposed above.
RealmResultsProxy.filteredunwraps its args, element-wise over arrays soIN $0is covered too. Confirmed against realm 12.14.2 that it rejects both a wrapper and an array of wrappers — though no caller writes anINquery today, so that half closes the gap rather than fixing a live break.c339a6d — write path (the extra bit). Reviewing the first fix turned up the same defect going the other way:
RealmListProxy.splice/unshiftforwarded values torealmListverbatim, wrappers included.RealmListProxy.pushreadx.thatunconditionally, so anything that wasn't a wrapper was written to realm asundefined.PersistedObject.fromEntityList(51 call sites) had the samex.thatidiom, while its neighbourfromObjectalready guarded against it.All four now route through one
unwrapForRealminRealmCollectionHelper.RealmProxy.create/deletekeep their own variants for now — hot paths, and their divergences want a change of their own.ArrayHelper.basePullAtis the live caller ofspliceand only ever deletes (no values), so it's unaffected — pinned by a test. No realm list holds primitives today, so theundefinedwrite was a dead path. Suite 402 → 415.Reaches avni-client only after a
v1.33.77publish; avni-client#2004's call-site workaround stays regardless.#2004 | Bump openchs-models to 1.33.77 for the realm 12 wrapper unwra…