Skip to content

Stop an own chat send from staying on Sending until reload #306

Description

@HMarzban

Problem

For a signed-in member, a message they send can stay in the pending state ("Sending") and never turn into sent. A
new comment can also fail to appear in the feed. A reload shows both, so the data is saved. The bug is older than
the 2026-09-21 composer round: a git archive HEAD copy of 7ed771158 does the same.

What was measured (local stack, 2026-09-21)

  • The inserts succeed: POST /rest/v1/messages returns 201, and the rows are in public.messages.
  • Realtime delivers them. A supabase-js probe subscribed to chatroom:<channelId> got each INSERT at once,
    both as anon and as the same signed-in user (row-level security as authenticated). The
    realtime.subscription rows exist, and both replication slots are caught up.
  • So the server side works, and the feed does not merge the echo.
  • In the page, the feed showed "No messages yet!" while it held one pending row. The "New messages" divider sat
    in the middle of the list. One send reached the database and was then missing from the list.

Lead

useChannelRealtime merges an arrival into the list only when dataIncludesTailRef.current is true.
Otherwise the arrival goes to detachedBufferRef and counts as "new", so an own optimistic row never turns
sent. The observations fit a loaded window that does not include the tail, or a window that lands after the send
and replaces the list (see the chatroom CLAUDE.md bullet "A purge replace lands late"). Next step: read
dataIncludesTailRef and newestSeqRef at the moment a send stays pending.

A second, unproven hypothesis: realtime-js 2.116 channel(topic) returns a still-listed channel with the same
topic, and removeChannel completes asynchronously. So a fast unsubscribe and resubscribe on one topic can reuse
a closing channel (React Strict Mode does this on mount in development). A fix for this alone did not change the
symptom, so it is not the cause shown here.

Steps to reproduce

  1. Sign in on the local stack. Open a pad, add a heading, open its chat.
  2. Send a message. Wait 10 seconds. It still shows the pending clock.
  3. Reload and open the same chat. The message is there as sent.

Acceptance criteria

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

    ChatRelated to chat featuresbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions