Skip to content

Follow-up: an explicit null on an optional payload field would blank the view #166

Description

@justin808

Problem

The client's payload guard treats an explicit null on an optional field as a type violation rather than as "absent", and because the guard is all-or-nothing, that rejects the entire payload and blanks the view.

In src/client/api.ts, the loops over RECORD_TEXT_FIELDS and RECORD_NUMBER_FIELDS, the SOURCE_TEXT_FIELDS loop in isRenderSource, and isOptionalString for message all special-case undefined only. An explicit null reaches isString/isFiniteNumber, returns false, and fails the whole payload.

This is not reachable today. projectAttentionRecord in src/shared/attention.ts returns undefined for an invalid or absent value, and JSON.stringify then omits the key, so the server cannot currently emit null for these fields. The genuinely nullable fields — target, walkthrough_url, open_uri — are handled separately and correctly.

What makes it worth filing is that nothing enforces that invariant across the boundary. The server's "omit, never null" behavior is an implementation detail of one function, the client's "null is a violation" behavior is an implementation detail of another, and the failure mode if they ever disagree is the whole dashboard going blank rather than one field degrading.

Proposed fix

Either accept null as absent in those four loops, which costs one predicate and removes the coupling, or assert the invariant on the server side so a regression there fails a test rather than a user's page. The first is cheaper and can be done independently; the second is the one that would have caught it.

This is closely related to #146, which proposes a per-field shape table for the projection, and to #164, on the same theme of the client depending on undocumented server behavior. Whoever picks up #146 should decide whether this collapses into it.

Evidence

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions