Skip to content

Inbox thread renders incomplete on every cold start — "Some message context could not be loaded.", missing messages, no retry (loses relay's 5s NIP-42 auth race) #4498

Description

@DrDoomi

Environment: Desktop 0.5.3 on macOS. Reproduces on both a self-hosted relay (0.2.0, deploy/compose-derived stack, BUZZ_REQUIRE_AUTH_TOKEN=true, BUZZ_REQUIRE_RELAY_MEMBERSHIP=true) and a fresh Builderlab-hosted community — so this is not deployment-specific.

Symptom: On every cold start of the desktop app, the Inbox detail pane shows the error banner "Some message context could not be loaded." (data-testid="home-inbox-context-error") — and the rendered thread is incomplete: messages are missing, not just auxiliary context. Leaving the Inbox and re-entering always fixes it; the missing messages then appear. There is no automatic retry.

Server-side evidence (from the self-hosted relay's logs): at app start, exactly one anomaly — a WebSocket connection that never completes NIP-42 auth and is closed by the relay after its 5-second window:

INFO WebSocket connection established  conn_id=53d608e8-…
WARN NIP-42 auth timeout — closing connection  conn_id=53d608e8-…  timeout_secs=5
INFO WebSocket connection closed  conn_id=53d608e8-…

All subsequent connections and queries in the same session succeed (NIP-42 auth successful, /query status=200). The relay behaves per spec; the client loses the auth race only on cold start — presumably because signing (keyring access) isn't ready yet in the first seconds after launch.

Code path (as of current main):

On startup the Inbox auto-selects an item; useInboxThreadContext (desktop/src/features/home/useInboxThreadContext.ts) immediately fires the fetches that hydrate the thread (ancestor chain + descendant replies).
At least one of these opens a WebSocket that must answer the relay's NIP-42 challenge; on cold start the signed AUTH response doesn't arrive within the relay's 5s window, the relay closes the socket, the fetch rejects.
The hook's generic catch sets hasLoadError = true (rendered in InboxDetailPane.tsx), and the events from the failed fetch are simply absent from displayMessages — the user sees a partial thread plus a subtle banner. There is no retry; re-entering the Inbox re-runs the effect, which then succeeds because the signer is warm.

Repro is 100% deterministic on both deployments (every cold start).

Please let me know if more information is needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions