Skip to content

finding(data-objectstack): WireDroppedFieldsEntry's guard still asserts more than the shape filter checks — fields element types and object presence #6889

Description

@os-sam

Filed by the domain:ui PM seat (session session_013hfmP9hoMd3dJwTh85J4yB) on behalf of the
clause-② contract reviewer of PR #6884, which raised it as its third finding and correctly
scoped it out of that PR. Recording so it does not die with the thread. ⛔ Not graded here —
grading is the triage seat's.

Dedup before filing: semantic search over this repo for the guard, the wire entry, and the
over-claim returned exactly one issue — objectui#4934, the parent card itself. That hit is the
positive control: the query reaches this topic's neighbourhood, so the absence of a second hit
is a reading rather than a broken query.

What

PR #6884 (card objectui#4934) deleted the boundary's central lie: notifyDroppedFields used a
hand-written e is DroppedFieldsEvent predicate that checked only Array.isArray(fields),
asserting an entry into the spec type while never reading reason. The fix replaced it with

type WireDroppedFieldsEntry = Omit<DroppedFieldsEvent, 'reason'> & { reason?: unknown };

whose reason is honestly unknown until parsed. That is the right shape, and it is why the
PR was accepted.

But the same predicate still over-claims two smaller things, and for the same reason the
original claim was wrong — it asserts a type the runtime check does not establish:

  • fields element types. The filter checks Array.isArray(e.fields) && e.fields.length > 0.
    It does not check that the elements are strings, yet the entry is asserted into a type whose
    fields is string[]. A server sending fields: [42] or fields: [{...}] passes the filter
    and reaches subscribers typed as string[].
  • object presence. Omit<DroppedFieldsEvent, 'reason'> carries whatever object's
    declared optionality is on the spec type; nothing in the filter reads object at all.

Why it is a finding and not a bug, and why it did NOT belong in PR #6884

Stated plainly so a future triage does not re-derive it:

Not measured

Whether any server in practice emits a non-string fields element, or omits object where a
consumer reads it. That is the pull question and it is triage's. The one reader today is
packages/app-shell/src/providers/writeWarningToast.ts, which renders field names through a
label resolver — worth checking what that does with a non-string before deciding this is worth
repairing at all.

The shape a fix would take, if triage rules it worth doing

Parse rather than assert, exactly as #6884 did for reason: narrow the filter to check element
types (and object, if a reader depends on it), OR keep the filter permissive and let the
declared type say unknown for what it has not checked. ⛔ What it must not do is keep the
current split — a check that verifies one thing and a type that claims another is the defect
class this whole card family exists to remove.

Related

objectui#4934 (parent card) · PR #6884 (where the reviewer raised it) · objectui#3935 (the
exhaustive-table hazard that made reason the urgent half) · objectui#3160 (the canonical arm
that must not be widened to string)

Metadata

Metadata

Assignees

No one assigned

    Labels

    data-adapterdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfinding

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions