Skip to content

The UI reports a failed read as an empty result, and the empty result gives advice #719

Description

@rainmanjam

From the poka-yoke audit of 2026-09-04. Lens: contact. Today: rung 3, for three files only. Device reaches: rung 2 (Warning). Silent.

The mistake available

Add a read to a dialog and use the empty array as the failure value.

ui/src/components/DestinationDialog.tsx:727,731,732,741,749:

api.listAccounts().then(setAccounts).catch(() => setAccounts([]));
api.listRenditions().then(setRenditions).catch(() => setRenditions([]));

ui/src/lib/readState.ts exists precisely to make that unwriteable. Its header
calls itself "a CONTROL rather than a warning" because mayClaim is a type
guard. This file never imports it.

What happens — and it drives the operator to act

  • A failed listRenditions() renders, at :1502, the sentence "No shared
    encodes yet. Create one on the Renditions page first."
    and disables the
    shared-encode radio. That is a positive claim, and it sends the operator to
    build a second real encode they do not need.
  • A failed listAccounts() replaces the account picker with a "Connect
    {platform} account"
    button linking to the OAuth consent flow
    (:1306-1310) — a re-authorisation for an account that is already linked,
    which also discards the half-filled dialog.

Today

Rung 3, and only for three files. ui/src/lib/readState.test.ts:51,72,73,74
enforces the rule by asserting that specific source string literals are
absent from SettingsPage.tsx and AutomationPage.tsx. That is a
hand-maintained list of filenames — training, not a device. It does not know
DestinationDialog.tsx exists.

Device → rung 2, Warning

An ESLint no-restricted-syntax rule matching a .catch() whose body is a
single setX([]) or setX(null), run as a required check.

Control would mean the read helpers in ui/src/lib/api.ts returning
ReadState<T>, so an empty array has no spelling on a failed read. strict: true
is on and there are only six anys repo-wide, so the type system is available —
but it touches every caller.

What stops the Warning today: there is no ESLint config in the repository
at all.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions